网络流 最大流HDU 3549



/
/
/
/
/
/
/
/
/
/

在这幅图中我们首先要增广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
",ca++,ans);
 96     }
 97 
 98     return 0;
 99 }
100   /*By--MJY*/
原文地址:https://www.cnblogs.com/cherryMJY/p/6036348.html