【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.
null