题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1532
题目大意:
给出有向图以及边的最大容量,求从1到n的最大流
思路:
传送门:最大流的增广路算法
直接套用模板,用水流来理解网络流
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 #include<queue> 7 using namespace std; 8 const int maxn = 1000; 9 const int INF = 1e9 + 7; 10 struct edge 11 { 12 int from, to, cap, flow;//分别是起点,终点,容量,流量 13 edge(int u, int v, int c, int f):from(u), to(v), cap(c), flow(f){} 14 }; 15 int n, m;//n为点数,m为边数 16 vector<edge>e;//保存所有边的信息 17 vector<int>G[maxn];//邻接表,G[i][j]保存节点i的第j条边在e数组里面的编号 18 int a[maxn];//每个点目前流经的水量 19 int p[maxn];//p[i]从原点s到终点t的节点i的前一条边的编号 20 21 void init(int n) 22 { 23 for(int i = 0; i <= n; i++)G[i].clear(); 24 e.clear(); 25 } 26 void addedge(int u, int v, int c) 27 { 28 e.push_back(edge(u, v, c, 0));//正向边 29 e.push_back(edge(v, u, 0, 0));//反向边,容量为0 30 m = e.size(); 31 G[u].push_back(m - 2); 32 G[v].push_back(m - 1); 33 } 34 int Maxflow(int s, int t)//起点为s,终点为t 35 { 36 int flow = 0; 37 for(;;) 38 { 39 memset(a, 0, sizeof(a));//从原点s开始放水,最初每个点的水量都为0 40 queue<int>Q;//BFS拓展队列 41 Q.push(s); 42 a[s] = INF;//原点的水设置成INF 43 while(!Q.empty()) 44 { 45 int x = Q.front();//取出目前水流到的节点 46 Q.pop(); 47 for(int i = 0; i < G[x].size(); i++)//所有邻接节点 48 { 49 edge& now = e[G[x][i]]; 50 if(!a[now.to] && now.cap > now.flow) 51 //a[i]为0表示i点还未流到 52 //now.cap > now.flow 说明这条路还没流满 53 //同时满足这两个条件,水流可以流过这条路 54 { 55 p[now.to] = G[x][i];//反向记录路径 56 a[now.to] = min(a[x], now.cap - now.flow); 57 //流到下一点的水量为上一点的水量或者路径上还可以流的最大流量,这两者取最小值 58 Q.push(now.to);//将下一个节点入队列 59 } 60 } 61 if(a[t])break;//如果已经流到了终点t,退出本次找增广路 62 } 63 if(!a[t])break;//如果所有路都已经试过,水不能流到终点,说明已经没有增广路,已经是最大流 64 for(int u = t; u != s; u = e[p[u]].from)//反向记录路径 65 { 66 e[p[u]].flow += a[t];//路径上所有正向边的流量增加流到终点的流量 67 e[p[u]^1].flow -= a[t];//路径上所有反向边的流量减少流到终点的流量 68 } 69 flow += a[t];//最大流加上本次流到终点的流量 70 } 71 return flow; 72 } 73 int main() 74 { 75 int M, N; 76 while(cin >> M >> N) 77 { 78 n = N; 79 int u, v, c; 80 init(n); 81 for(int i = 0; i < M; i++) 82 { 83 scanf("%d%d%d", &u, &v, &c); 84 addedge(u, v, c); 85 } 86 cout<<Maxflow(1, n)<<endl; 87 } 88 return 0; 89 }