网络流 最大流HDU 3549
![](https://images2015.cnblogs.com/blog/1058376/201611/1058376-20161106210717033-1776908981.png)
/
/
/
/
/
/
/
/
/
/
在这幅图中我们首先要增广1->2->4->6,这时可以获得一个容量为2的流,但是如果不建立4->2反向弧的话,则无法进一步增广,
最终答案为2,显然是不对的,然而如果建立了反向弧4->2,则第二次能进行1->3->4->2->5->6的增广,最大流为3.
1 #include<stdio.h> 2 #include<algorithm> 3 #include<string.h> 4 #include<queue> 5 typedef long long LL; 6 7 using namespace std; 8 int n,m; 9 #define inf 100000000 10 #define MAXN 5000 11 #define MAXN1 50 12 struct edg 13 { 14 int w,to,next; 15 }x[MAXN+10]; 16 int head[MAXN1],cnt; 17 int vis[MAXN1]; 18 19 void add(int u,int v,int w) 20 { 21 x[cnt].next=head[u]; 22 x[cnt].to=v; 23 x[cnt].w=w; 24 head[u]=cnt++; 25 x[cnt].next=head[v]; 26 x[cnt].to=u; 27 x[cnt].w=0; 28 head[v]=cnt++; 29 } 30 queue<int>q1; 31 32 int bfs() //层次网络 33 { 34 memset(vis,-1,sizeof(vis)); 35 vis[1]=0; 36 q1.push(1); 37 while(!q1.empty()) 38 { 39 int now=q1.front(); 40 q1.pop(); 41 int j; 42 for(j=head[now];j!=-1;j=x[j].next) 43 { 44 if(vis[x[j].to]<0&&x[j].w) 45 { 46 vis[x[j].to]=vis[now]+1; 47 q1.push(x[j].to); 48 } 49 } 50 } 51 if(vis[n]<0) //汇点不在网络 结束 52 return 0; 53 return 1; 54 } 55 int dfs(int u,int w) 56 { 57 if(u==n) 58 return w; 59 int j; 60 int ans=0; 61 62 for(j=head[u];j!=-1&&ans<=w;j=x[j].next) 63 { 64 if(vis[x[j].to]==vis[u]+1&&x[j].w) 65 { 66 int b=dfs(x[j].to,min(w-ans,x[j].w)); //流进去的有2个限制 min(总流量减去已经流掉的,可以流进去的) 67 x[j].w-=b; 68 x[j^1].w+=b; //cnt=0 开始 反向边下标=j^1 可以自己试试 69 ans+=b; 70 } 71 } 72 return ans; 73 } 74 int main() 75 { 76 int t,ca; 77 78 scanf("%d",&t); 79 ca=1; 80 while(t--) 81 { 82 scanf("%d%d",&n,&m); 83 cnt=0; 84 memset(head,-1,sizeof(head)); 85 int i,j; 86 for(i=1;i<=m;i++) 87 { 88 int u,v,w; 89 scanf("%d%d%d",&u,&v,&w); 90 add(u,v,w); //建边 有反向边 91 } 92 int ans=0; 93 while(bfs()) //Dinic bfs+dfs 94 ans+=dfs(1,inf); 95 printf("Case %d: %d\n",ca++,ans); 96 } 97 98 return 0; 99 } 100 /*By--MJY*/
posted on 2016-11-06 20:59 HelloWorld!--By-MJY 阅读(513) 评论(1) 编辑 收藏 举报