poj 1273 Drainage Ditches (网络流 最大流)
题目链接:
http://poj.org/problem?id=1273
题目大意:
n条边,m个点,每条边都有一个最大流量,问,源点1到汇点m的最大流?
解题思路:
模板网络流,要注意的是会有重边。(~_~很小白,模板网络流,但是我还是想发博,毕竟第一道网络流嘛,也算是丰富博客内容。。。。。)
代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <algorithm> 5 #include <iostream> 6 #include <cmath> 7 #include <queue> 8 using namespace std; 9 10 #define maxn 0x3f3f3f3f 11 #define N 210 12 int map[N][N], Layer[N], n, m; 13 bool visit[N]; 14 15 bool CountLayer (); 16 int Dinic (); 17 int main () 18 { 19 while (scanf ("%d %d", &n, &m) != EOF) 20 { 21 int s, e, v; 22 memset (map, 0, sizeof(map)); 23 for (int i=0; i<n; i++) 24 { 25 scanf ("%d %d %d", &s, &e, &v); 26 map[s][e] += v;//会出现重复边 27 } 28 printf ("%d\n", Dinic()); 29 } 30 return 0; 31 } 32 33 bool CountLayer () 34 {//给残余网络分层 35 deque <int> Q; 36 memset (Layer, -1, sizeof(Layer));//初始化层编号为-1 37 Layer[1] = 1;//初始化源点 38 Q.push_back(1);//源点进队 39 while (!Q.empty()) 40 { 41 int nd = Q.front(); 42 Q.pop_front(); 43 for (int i=1; i<=m; i++) 44 { 45 if (map[nd][i] > 0 && Layer[i] == -1) 46 { 47 Layer[i] = Layer[nd] + 1; 48 if (i == m)//分层到汇点就可以停止了 49 return true; 50 else 51 Q.push_back(i); 52 } 53 } 54 } 55 return false; 56 } 57 int Dinic () 58 { 59 int maxnflow = 0; 60 while (CountLayer()) 61 {//能够分层成功就存在增广路 62 deque <int> Q;//dfs队列 63 memset (visit, 0, sizeof(visit)); 64 visit[1] = 1;//源点入队 65 Q.push_back(1); 66 while (!Q.empty()) 67 { 68 int nd = Q.back(), i; 69 if (nd != m) 70 { 71 for (i=1; i<=m; i++) 72 { 73 if (map[nd][i] > 0 && Layer[nd] + 1 == Layer[i] && !visit[i]) 74 {//dfs下一层,没有走过的节点 75 visit[i] = 1; 76 Q.push_back(i); 77 break; 78 } 79 } 80 if (i > m)//在下一层里找不到点,退出本层点,以便继续dfs 81 Q.pop_back(); 82 } 83 else//末点是汇点,则找到一条增广路经 84 { 85 int mflow = maxn;//增广流量 86 int mv;//最小容量边的起点 87 for (i=1; i<Q.size(); i++) 88 {//遍历经过的边,路径上容量最小的边,就是增广流量 89 int ns, ne; 90 ns = Q[i-1]; 91 ne = Q[i]; 92 if (map[ns][ne] < mflow) 93 { 94 mflow = map[ns][ne]; 95 mv = ns; 96 } 97 } 98 maxnflow += mflow;//增广,改图 99 for (i=1; i<Q.size(); i++) 100 { 101 int ns, ne; 102 ns = Q[i-1]; 103 ne = Q[i]; 104 map[ns][ne] -= mflow;//修改边容量 105 map[ne][ns] += mflow;//增加反向边 106 } 107 while (!Q.empty() && Q.back() != mv) 108 Q.pop_back();//出队,以便增广下一条路径 109 } 110 } 111 } 112 return maxnflow; 113 }
本文为博主原创文章,未经博主允许不得转载。