【BZOJ3504】危桥(最大流)

题意:见题面

思路:http://www.cnblogs.com/chenyushuo/p/5139556.html

必须交换b1,b2做第二次最大流的原因:

假如一个a1到b2的一个流和b1到a2的一个流分别经过了一个桥的两个端点(u,v),如图

我们就可以将a1到b2的流量改为经过u-v-a2-T到达T,同理将b1到a2的流量改为经过v-u-b2-T到达T,这样就说明这个流是没有问题的
在这种情况下将b1和b2交换后,流量显然不会有变化
如果一个a1到b2的一个流和b1到a2的一个流没有经过任何一个桥的两个端点,这个流显然不合法,且在b1和b2交换后,流量会减小
  1 var fan:array[1..200000]of longint;
  2     head,vet,next,gap,len,dis:array[0..50000]of longint;
  3     a:array[1..100,1..100]of char;
  4     ch:string;
  5     n,m,i,tot,x1,x2,y1,y2,s1,s2,src,source,s,j:longint;
  6     flag:boolean;
  7 
  8 function min(x,y:longint):longint;
  9 begin
 10  if x<y then exit(x);
 11  exit(y);
 12 end;
 13 
 14 procedure add(a,b,c:longint);
 15 begin
 16  inc(tot);
 17  next[tot]:=head[a];
 18  vet[tot]:=b;
 19  len[tot]:=c;
 20  head[a]:=tot;
 21 
 22  inc(tot);
 23  next[tot]:=head[b];
 24  vet[tot]:=a;
 25  len[tot]:=0;
 26  head[b]:=tot;
 27 end;
 28 
 29 function dfs(u,aug:longint):longint;
 30 var e,v,t,val,flow:longint;
 31 begin
 32  if u=src then exit(aug);
 33  e:=head[u]; flow:=0; val:=s-1;
 34  while e<>0 do
 35  begin
 36   v:=vet[e];
 37   if len[e]>0 then
 38   begin
 39    if dis[u]=dis[v]+1 then
 40    begin
 41     t:=dfs(v,min(len[e],aug-flow));
 42     len[e]:=len[e]-t;
 43     len[fan[e]]:=len[fan[e]]+t;
 44     flow:=flow+t;
 45     if dis[source]>=s then exit(flow);
 46     if aug=flow then break;
 47    end;
 48    val:=min(val,dis[v]);
 49   end;
 50   e:=next[e];
 51  end;
 52  if flow=0 then
 53  begin
 54   dec(gap[dis[u]]);
 55   if gap[dis[u]]=0 then dis[source]:=s;
 56   dis[u]:=val+1;
 57   inc(gap[dis[u]]);
 58  end;
 59  exit(flow);
 60 end;
 61 
 62 function maxflow:longint;
 63 var ans:longint;
 64 begin
 65  fillchar(gap,sizeof(gap),0);
 66  fillchar(dis,sizeof(dis),0);
 67  gap[0]:=s; ans:=0;
 68  while dis[source]<s do ans:=ans+dfs(source,maxlongint);
 69  exit(ans);
 70 end;
 71 
 72 procedure build;
 73 var i,j:longint;
 74 begin
 75  for i:=1 to n do
 76   for j:=1 to n do
 77   begin
 78    if a[i,j]='O' then add(i,j,2);
 79    if a[i,j]='N' then add(i,j,maxlongint);
 80   end;
 81 end;
 82 
 83 begin
 84  assign(input,'bzoj3504.in'); reset(input);
 85  assign(output,'bzoj3504.out'); rewrite(output);
 86  for i:=1 to 200000 do
 87   if i mod 2=1 then fan[i]:=i+1
 88    else fan[i]:=i-1;
 89  while not eof do
 90  begin
 91   readln(n,x1,y1,s1,x2,y2,s2);
 92   if n=0 then break;
 93   inc(x1); inc(y1); inc(x2); inc(y2);
 94   tot:=0; for i:=1 to n+2 do head[i]:=0;
 95   for i:=1 to n do
 96   begin
 97    readln(ch);
 98    for j:=1 to n do a[i,j]:=ch[j];
 99   end;
100   s:=n; source:=s+1; src:=s+2; s:=s+2;
101   build;
102   add(source,x1,2*s1);
103   add(source,x2,2*s2);
104   add(y1,src,2*s1);
105   add(y2,src,2*s2);
106   flag:=true;
107   if maxflow<2*(s1+s2) then flag:=false;
108   if flag then
109   begin
110    tot:=0; for i:=1 to n+2 do head[i]:=0;
111    build;
112    add(source,x1,2*s1);
113    add(source,y2,2*s2);
114    add(y1,src,2*s1);
115    add(x2,src,2*s2);
116    if maxflow<2*(s1+s2) then flag:=false;
117   end;
118   if flag then writeln('Yes')
119    else writeln('No');
120  end;
121  close(input);
122  close(output);
123 end.

 

 

posted on 2016-12-20 20:01  myx12345  阅读(191)  评论(0编辑  收藏  举报

导航