bzoj3504: [Cqoi2014]危桥(网络流)
3504: [Cqoi2014]危桥
题目:传送门
题解:
一开始觉得要跑四次网络流...但是想想好像两次?
st-->a1/b1 a2/b2-->ed
好像这样也OK?但是a1流b2或者b1流到a2怎么办?完了...又想错了。
问了一波zzz大佬,他说我没想错...
把b1和b2换过来再流一次的话...那原本a1流到b2的流量流到b1再流到a2那不就是相当于a1可以流到a2咯
每次跑完都看一下流量是不是等于an+bn就好啦。
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cmath> 5 #include<algorithm> 6 #define inf 999999999 7 using namespace std; 8 struct node 9 { 10 int x,y,c,next,other; 11 }a[210000];int len,last[110]; 12 int n,a1,a2,an,b1,b2,bn,st,ed; 13 void ins(int x,int y,int c) 14 { 15 int k1,k2; 16 k1=++len; 17 a[len].x=x;a[len].y=y;a[len].c=c; 18 a[len].next=last[x];last[x]=len; 19 k2=++len; 20 a[len].x=y;a[len].y=x;a[len].c=0; 21 a[len].next=last[y];last[y]=len; 22 23 a[k1].other=k2; 24 a[k2].other=k1; 25 } 26 int list[210000],h[110],head,tail; 27 bool bt_h() 28 { 29 list[1]=st;head=1;tail=2; 30 memset(h,0,sizeof(h)); 31 h[st]=1; 32 while(head!=tail) 33 { 34 int x=list[head]; 35 for(int k=last[x];k;k=a[k].next) 36 { 37 int y=a[k].y; 38 if(a[k].c>0 && h[y]==0) 39 { 40 h[y]=h[x]+1; 41 list[tail++]=y; 42 } 43 } 44 head++; 45 } 46 if(h[ed]==0)return false; 47 return true; 48 } 49 int find_flow(int x,int flow) 50 { 51 if(x==ed)return flow; 52 int s=0,t; 53 for(int k=last[x];k;k=a[k].next) 54 { 55 int y=a[k].y; 56 if(h[y]==h[x]+1 && a[k].c>0 && s<flow) 57 { 58 s+=(t=find_flow(y,min(a[k].c,flow-s))); 59 a[k].c-=t;a[a[k].other].c+=t; 60 } 61 } 62 if(s==0)h[x]=0; 63 return s; 64 } 65 char ss[55][55]; 66 int main() 67 { 68 while(scanf("%d%d%d%d%d%d%d",&n,&a1,&a2,&an,&b1,&b2,&bn)!=EOF) 69 { 70 len=0;memset(last,0,sizeof(last)); 71 a1++;a2++;b1++;b2++;st=n+1;ed=n+2;int sum=2*an+2*bn; 72 for(int i=1;i<=n;i++)scanf("%s",ss[i]+1); 73 74 for(int i=1;i<=n;i++) 75 for(int j=1;j<=n;j++) 76 if(ss[i][j]=='N')ins(i,j,inf); 77 else if(ss[i][j]=='O')ins(i,j,2); 78 ins(st,a1,2*an);ins(a2,ed,2*an); 79 ins(st,b1,2*bn);ins(b2,ed,2*bn); 80 int ans=0; 81 while(bt_h())ans+=find_flow(st,inf); 82 if(ans!=sum){printf("No\n");continue;} 83 //反过来 84 len=0;memset(last,0,sizeof(last)); 85 for(int i=1;i<=n;i++) 86 for(int j=1;j<=n;j++) 87 { 88 if(ss[i][j]=='N')ins(i,j,inf); 89 else if(ss[i][j]=='O')ins(i,j,2); 90 } 91 ins(st,a1,2*an);ins(a2,ed,2*an); 92 ins(st,b2,2*bn);ins(b1,ed,2*bn); 93 ans=0; 94 while(bt_h())ans+=find_flow(st,inf); 95 96 if(ans!=sum){printf("No\n");continue;} 97 else printf("Yes\n"); 98 } 99 return 0; 100 }