BZOJ1001 狼抓兔子
裸的网络流,这里要注意对于无向图建图可以将反向图的边改为一样的,这样可以减少一半边数。
还有一个优化就是如果当前这个点已经无法延伸则堵死。
By:大奕哥
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,m,head[1000005],cnt=-1,v[1000005],ans; 4 struct node 5 { 6 int to,w,nex; 7 }e[6000005]; 8 void add(int x,int y,int w) 9 { 10 e[++cnt].to=y;e[cnt].nex=head[x];head[x]=cnt;e[cnt].w=w; 11 e[++cnt].to=x;e[cnt].nex=head[y];head[y]=cnt;e[cnt].w=w; 12 } 13 queue<int>q; 14 bool bfs(int s,int t) 15 { 16 memset(v,-1,sizeof(v)); 17 q.push(s);v[s]=0;int y; 18 while(!q.empty()) 19 { 20 int x=q.front();q.pop(); 21 for(int i=head[x];i!=-1;i=e[i].nex) 22 { 23 y=e[i].to; 24 if(e[i].w==0||v[y]!=-1)continue; 25 v[y]=v[x]+1;q.push(y); 26 } 27 } 28 return v[t]!=-1; 29 } 30 31 int dfs(int s,int w,int t) 32 { 33 if(s==t||!w)return w;int sum=0,f=0;int y; 34 for(int i=head[s];i!=-1;i=e[i].nex) 35 { 36 y=e[i].to; 37 if(v[y]==v[s]+1&&e[i].w) 38 { 39 f=dfs(y,min(e[i].w,w-sum),t); 40 if(!f)v[y]=-1;//就是这里 41 e[i].w-=f;e[i^1].w+=f;sum+=f; 42 if(sum==w)return sum; 43 } 44 } 45 return sum; 46 } 47 void dinic(int s,int t) 48 { 49 while(bfs(s,t)){ans+=dfs(s,1e9,t);} 50 } 51 int main() 52 { 53 scanf("%d%d",&n,&m);int w; 54 if(n==1&&m==1){ 55 puts("0");return 0; 56 } 57 memset(head,-1,sizeof(head)); 58 for(int i=1;i<=n;++i) 59 { 60 for(int j=1;j<m;++j) 61 { 62 scanf("%d",&w); 63 add((i-1)*m+j,(i-1)*m+j+1,w); 64 } 65 } 66 for(int i=1;i<n;++i) 67 { 68 for(int j=1;j<=m;++j) 69 { 70 scanf("%d",&w); 71 add((i-1)*m+j,i*m+j,w); 72 } 73 } 74 for(int i=1;i<n;++i) 75 { 76 for(int j=1;j<m;++j) 77 { 78 scanf("%d",&w); 79 add((i-1)*m+j,i*m+j+1,w); 80 } 81 } 82 dinic(1,n*m); 83 printf("%d",ans); 84 return 0; 85 }
生命中真正重要的不是你遭遇了什么,而是你记住了哪些事,又是如何铭记的。