最大流——增广路算法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最大流——增广路算法相关的知识,希望对你有一定的参考价值。

关于网络流的增广路算法,网上有很多详细介绍,这里是摘录的模板。详细请见:http://www.cnblogs.com/kuangbin/archive/2011/07/26/2117636.html

 1 #include<iostream>
 2 #include<iomanip>
 3 #include<ctime>
 4 #include<climits>
 5 #include<algorithm>
 6 #include<queue>
 7 #include<vector>
 8 #include<cstring>
 9 #include<cstdio>
10 #include<cstdlib>
11 #include<map>
12 using namespace std;
13 typedef unsigned long long LL;
14 #define rep(i,a,b) for(int i=a;i<=b;i++)
15 #define dep(i,a,b) for(int i=a;i>=b;i--)
16 int n,m;
17 const int M=201;
18 int G[M][M];//残量网络,初始为给定的流网络
19 int road[M];//记录增广路中各点的前驱
20 int F[M];//记录增广路中到达当前点的最大流量
21 queue<int>q;//利用队列实现bfs
22 int bfs(){
23     memset(road,-1,sizeof(road));
24     while(!q.empty())q.pop();
25 //默认为源点为1节点,汇点为n节点
26     q.push(1);
27     road[1]=0;F[1]=INT_MAX;
28     while(!q.empty()){
29         int u=q.front();
30         q.pop();
31         if(u==n)break;//已经找到增广路,直接退出
32         rep(i,1,n){
33             if(road[i]==-1&&G[u][i]){//当前节点未被访问,且边(u,i)在残量网络中
34                 road[i]=u;
35                 F[i]=min(F[u],G[u][i]);
36                 q.push(i);
37             }
38         }
39     }
40     if(road[n]==-1)return -1;
41     return F[n];
42 }
43 int main(){
44     scanf("%d%d",&m,&n);
45     memset(G,0,sizeof(G));
46     rep(i,1,m){
47         int u,v;
48         scanf("%d%d",&u,&v);
49         scanf("%d",&G[u][v]);
50     }
51 
52     int ans=0,add;
53     while((add=bfs())!=-1){
54         ans+=add;
55         int now=n;
56         while(now!=1){
57             int pre=road[now];
58             G[pre][now]-=add;//更新残量网络中的边
59             G[now][pre]+=add;//添加反向边
60             now=pre;
61         }
62     }
63     printf("%d",ans);
64 }

 应用:BZOJ1001狼抓兔子

以上是关于最大流——增广路算法的主要内容,如果未能解决你的问题,请参考以下文章

线性规划网络流之最短增广路算法

图论之最大流问题(三)

最大网络流——增广路算法

Dinic算法最大流入门

最大流——EK算法

最大流学习笔记