bzoj 1066 最大流

来源:互联网 发布:初级程序员教程 编辑:程序博客网 时间:2024/06/16 14:22

题意:r行c列的网络中有一些高低不同的石柱,每行每列相邻石柱距离为1,一些石柱上有蜥蜴,每个蜥蜴可以跳到平面距离不超过d的任意石柱上。每次蜥蜴跳跃时离开的石柱高度减一,到达的石柱高度不变。当石柱高度为0时其他蜥蜴不能落脚。任意时刻同一个石柱上不能有超过一只的蜥蜴。让尽量多的蜥蜴逃到边界外,输出无法逃离的蜥蜴。即输出无法蜥蜴的最小值。

最大流

建图:源点连每个有蜥蜴的柱子,流量为1每个能跳到边界外的柱子(初始高度大于0的)连汇点,流量为正无穷;由于每个柱子有能走蜥蜴的限制,把每个柱子(初始高度大于0的)拆成出入两个点,每个柱子的出入两个点之间流量为石柱高度(能走蜥蜴的总数),每个出点连能到达的柱子的入点,流量为正无穷

var        n,m,d,l,ss,st   :longint;        s               :string;        ans,sum,x       :longint;        i,j,ii,jj       :longint;        last            :array[0..1010] of longint;        dis             :array[0..1010] of longint;        que             :array[0..1010] of longint;        pre,other,len   :array[0..170010] of longint;        num             :array[0..25,0..25] of longint;        map,jump        :array[0..25,0..25] of char;function min(a,b:longint):longint;begin   if a<b then exit(a) else exit(b);end;procedure connect(x,y,z:longint);begin   inc(l);   pre[l]:=last[x];   last[x]:=l;   other[l]:=y;   len[l]:=z;end;function bfs:boolean;var        p,q,cur,h,tl:longint;begin   fillchar(dis,sizeof(dis),0);   h:=0;tl:=1;   que[1]:=ss;dis[ss]:=1;   while (h<>tl) do   begin      h:=h mod 805+1;      cur:=que[h];      q:=last[cur];      while (q<>0) do      begin         p:=other[q];         if (len[q]>0) and (dis[p]=0) then         begin            tl:=tl mod 805+1;            que[tl]:=p;            dis[p]:=dis[cur]+1;            if p=st then exit(true);         end;         q:=pre[q];      end;   end;   exit(false);end;function dinic(x,flow:longint):longint;var        p,q:longint;        rest,tt:longint;begin   if (x=st) then exit(flow);   rest:=flow;   q:=last[x];   while (q<>0) do   begin      p:=other[q];      if (dis[x]+1=dis[p]) and (len[q]>0) and (rest>0) then      begin         tt:=dinic(p,min(rest,len[q]));         dec(rest,tt);         dec(len[q],tt);         inc(len[q xor 1],tt);      end;      q:=pre[q];   end;   exit(flow-rest);end;begin   readln(n,m,d);l:=1;   for i:=1 to n do   begin      readln(s);      for j:=1 to m do map[i,j]:=s[j];   end;   for i:=1 to n do   begin      readln(s);      for j:=1 to m do jump[i,j]:=s[j];   end;   //   ss:=n*m*2+1;st:=ss+1;   for i:=1 to n do     for j:=1 to m do num[i,j]:=m*(i-1)+j;   //   sum:=0;   for i:=1 to n do     for j:=1 to m do       if (jump[i,j]='L') then       begin          connect(ss,num[i,j],1);          connect(num[i,j],ss,0);          inc(sum);       end;   //   for i:=1 to n do     for j:=1 to m do       if (map[i,j]<>'0') then       begin          for ii:=1 to n do            for jj:=1 to m do              if ((i-ii)*(i-ii)+(j-jj)*(j-jj)<=d*d) and ((i<>ii) or (j<>jj)) then              begin                 connect(num[i,j]+n*m,num[ii,jj],maxlongint div 10);                 connect(num[ii,jj],num[i,j]+n*m,0);              end;       end;   //   for i:=1 to d do     for j:=1 to m do       if (map[i,j]<>'0') then       begin          connect(num[i,j]+n*m,st,maxlongint div 10);          connect(st,num[i,j]+n*m,0);       end;   for i:=1 to n do     for j:=1 to d do       if (map[i,j]<>'0') then       begin          connect(num[i,j]+n*m,st,maxlongint div 10);          connect(st,num[i,j]+n*m,0);       end;   for i:=n-d+1 to n do     for j:=1 to m do       if (map[i,j]<>'0') then       begin          connect(num[i,j]+n*m,st,maxlongint div 10);          connect(st,num[i,j]+n*m,0);       end;   for i:=1 to n do     for j:=m-d+1 to m do       if (map[i,j]<>'0') then       begin          connect(num[i,j]+n*m,st,maxlongint div 10);          connect(st,num[i,j]+n*m,0);       end;   //   for i:=1 to n do     for j:=1 to m do       if (map[i,j]<>'0') then       begin          val(map[i,j],x);          connect(num[i,j],num[i,j]+n*m,x);          connect(num[i,j]+n*m,num[i,j],0);       end;   //   ans:=0;   while bfs do inc(ans,dinic(ss,maxlongint div 10));   writeln(sum-ans);end.
——by Eirlys


0 0
原创粉丝点击