zoukankan      html  css  js  c++  java
  • bzoj 1066 最大流

    将每个石柱拆成两个点,分别是进入的和出去的,两个点之间连石柱的高度

    然后每个出去的点连别的石柱的进去的点,

    源点连所有蜥蜴所在柱子,每个能跳出去的连汇点,然后最大流就行了

    /**************************************************************
        Problem: 1066
        User: BLADEVIL
        Language: Pascal
        Result: Accepted
        Time:48 ms
        Memory:2748 kb
    ****************************************************************/
     
    //By BLADEVIL
    var
        r, c, d                             :longint;
        map, jump                           :array[0..300,0..300] of char;
        pre, other, len                     :array[0..100010] of longint;
        last                                :array[0..10100] of longint;
        num                                 :array[0..300,0..300] of longint;
        source, sink                        :longint;
        l                                   :longint;
        que, dis                            :array[0..100000] of longint;
        ans, sum                            :longint;
         
    function min(a,b:longint):longint;
    begin
        if a>b then min:=b else min:=a;
    end;
         
    procedure connect(x,y,z:longint);
    begin
        inc(l);
        pre[l]:=last[x];
        last[x]:=l;
        other[l]:=y;
        len[l]:=z;
    end;
         
    procedure init;
    var
        i, j, ii, jj                        :longint;
        k                                   :longint;
         
    begin
        readln(r,c,d); l:=1;
        for i:=1 to r do
        begin
            for j:=1 to c do
                read(map[i,j]);
            readln;
        end;
         
        for i:=1 to r do
        begin
            for j:=1 to c do read(jump[i,j]);
            readln;
        end;
         
        for i:=1 to r do
            for j:=1 to c do num[i,j]:=c*(i-1)+j;
        source:=2*r*c+2; sink:=source+1;
         
        for i:=1 to r do
            for j:=1 to c do
                if jump[i,j]='L' then
                begin
                    connect(source,num[i,j],1);
                    connect(num[i,j],source,0);
                    inc(sum);
                end;
         
        for i:=1 to r do
            for j:=1 to c do
                if map[i,j]<>'0' then
                begin
                    for ii:=1 to r do
                        for jj:=1 to c do
                            //if (i<>ii) or (j<>jj) then
                            begin
                                if (sqrt((i-ii)*(i-ii)+(j-jj)*(j-jj))<=d) then
                                begin
                                    connect(num[i,j]+r*c,num[ii,jj],maxlongint div 10);
                                    connect(num[ii,jj],num[i,j]+r*c,0);
                                end;
                            end;    
                end;
     
        for i:=1 to d do
            for j:=1 to c do
                if map[i,j]<>'0' then
                begin
                    connect(num[i,j]+r*c,sink,maxlongint div 10);
                    connect(sink,num[i,j]+r*c,0);
                end;
        for i:=r-d+1 to r do
            for j:=1 to c do
                if map[i,j]<>'0' then
                begin
                    connect(num[i,j]+r*c,sink,maxlongint div 10);
                    connect(sink,num[i,j]+r*c,0);
                end;
        for i:=1 to r do
            for j:=1 to d do
                if map[i,j]<>'0' then
                begin
                    connect(num[i,j]+r*c,sink,maxlongint div 10);
                    connect(sink,num[i,j]+r*c,0);
                end;
                 
        for i:=1 to r do
            for j:=c-d+1 to c do
                if map[i,j]<>'0' then
                begin
                    connect(num[i,j]+r*c,sink,maxlongint div 10);
                    connect(sink,num[i,j]+r*c,0);
                end;
        for i:=1 to r do   
            for j:=1 to c do
                if map[i,j]<>'0' then
                begin
                    k:=ord(map[i,j])-48;
                    connect(num[i,j],num[i,j]+r*c,k);
                    connect(num[i,j]+r*c,num[i,j],0);
                end;
    end;
     
    function bfs:boolean;
    var
        h, t, cur                           :longint;
        q, p                                :longint;
    begin
        fillchar(dis,sizeof(dis),0);
        h:=0; t:=1;
        que[1]:=source; dis[source]:=1;
        while h<t do
        begin
            inc(h);
            cur:=que[h];
            q:=last[cur];
            while q<>0 do
            begin
                p:=other[q];
                if (len[q]>0) and (dis[p]=0) then
                begin
                    inc(t);
                    que[t]:=p;
                    dis[p]:=dis[cur]+1;
                    if p=sink then exit(true);
                end;
                q:=pre[q];
            end;
        end;
        exit(false);
    end;
     
    function dinic(x,flow:longint):longint;
    var
        tmp, rest                           :longint;
        q, p                                :longint;
    begin
        if x=sink then exit(flow);
        rest:=flow;
        q:=last[x];
        while q<>0 do
        begin
            p:=other[q];
            if (dis[x]=dis[p]-1) and (len[q]>0) and (rest>0) then
            begin
                tmp:=dinic(p,min(rest,len[q]));
                dec(rest,tmp);
                dec(len[q],tmp);
                inc(len[q xor 1],tmp);
            end;
            q:=pre[q];
        end;
        exit(flow-rest);
    end;
         
         
    procedure main;
    begin
        while bfs do
            ans:=ans+dinic(source,maxlongint div 10);
        writeln(sum-ans);
    end;
         
    begin
        init;
        main;
    end.
  • 相关阅读:
    Android笔记——UI开发
    P2P网络借贷系统-核心功能-用户投标-业务解说
    java回调简单实现
    Java面向对象编程(二)
    POJ-1190-生日蛋糕-DFS(深搜)-枚举-多重剪枝
    设计模式笔记——装饰模式
    bbed初体验
    高速理解环境变量
    最短路算法之 Dijkstra算法
    C++课程资源下载问题
  • 原文地址:https://www.cnblogs.com/BLADEVIL/p/3489045.html
Copyright © 2011-2022 走看看