Poj--1273(最大流)
2014-12-20 00:56:43
思路:最大流启蒙题(启蒙好晚orz....)
研究了一下Fork-Fulkerson、EK和Dinic,前两者差别就在与用DFS还是BFS来找增广路,Dinic的话采用了分层图的概念,优化了增广路多次查找过程。
总结下:(1)基于流的边反对称性、非源/汇点出入守恒、增广路定理(同理于二分匹配)三大原理(2)通过构造“反向边”的概念使得找增广路算法可以“反悔”
(3)通过不断增广来增加流量,最终达到最大流。
分别用EK、FF、Dinic实现了下。
EK:
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <stack> 9 #include <queue> 10 #include <iostream> 11 #include <algorithm> 12 using namespace std; 13 #define lp (p << 1) 14 #define rp (p << 1|1) 15 #define getmid(l,r) (l + (r - l) / 2) 16 #define MP(a,b) make_pair(a,b) 17 typedef long long ll; 18 typedef unsigned long long ull; 19 const int INF = 1 << 30; 20 const int maxn = 210; 21 22 int pre[maxn],c[maxn][maxn],n,m; 23 bool vis[maxn]; 24 queue<int> Q; 25 26 bool Bfs(){ 27 while(!Q.empty()) Q.pop(); 28 memset(vis,false,sizeof(vis)); 29 memset(pre,-1,sizeof(pre)); 30 vis[1] = true; 31 Q.push(1); 32 while(!Q.empty()){ 33 int x = Q.front(); Q.pop(); 34 for(int i = 1; i <= m; ++i) if(!vis[i] && c[x][i] > 0){ 35 pre[i] = x; 36 vis[i] = true; 37 if(i == m) return true; 38 Q.push(i); 39 } 40 } 41 return false; 42 } 43 44 int EK(){ 45 int max_flow = 0,plus; 46 while(Bfs()){ 47 plus = INF; 48 for(int i = m; i != 1; i = pre[i]) plus = min(plus,c[pre[i]][i]); 49 for(int i = m; i != 1; i = pre[i]){ 50 c[pre[i]][i] -= plus; 51 c[i][pre[i]] += plus; 52 } 53 max_flow += plus; 54 } 55 return max_flow; 56 } 57 58 int main(){ 59 int v1,v2,v3; 60 while(scanf("%d%d",&n,&m) != EOF){ 61 memset(c,0,sizeof(c)); 62 for(int i = 1; i <= n; ++i){ 63 scanf("%d%d%d",&v1,&v2,&v3); 64 c[v1][v2] += v3; 65 } 66 printf("%d\n",EK()); 67 } 68 return 0; 69 }
FF:
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <stack> 9 #include <queue> 10 #include <iostream> 11 #include <algorithm> 12 using namespace std; 13 #define lp (p << 1) 14 #define rp (p << 1|1) 15 #define getmid(l,r) (l + (r - l) / 2) 16 #define MP(a,b) make_pair(a,b) 17 typedef long long ll; 18 typedef unsigned long long ull; 19 const int INF = 1 << 30; 20 const int maxn = 210; 21 22 int c[maxn][maxn],n,m; 23 bool vis[maxn]; 24 25 int Dfs(int p,int minc){ 26 if(p == m) return minc; 27 vis[p] = true; 28 for(int i = 1; i <= m; ++i) if(!vis[i] && c[p][i] > 0){ 29 int d = Dfs(i,min(minc,c[p][i])); 30 if(d > 0){ //一旦发现就该返回,因为就找一条增广路 31 c[p][i] -= d; 32 c[i][p] += d; 33 return d; 34 } 35 } 36 return 0; 37 } 38 39 int FF(){ 40 int plus,max_flow = 0; 41 while(1){ 42 memset(vis,false,sizeof(vis)); 43 plus = Dfs(1,INF); 44 if(plus == 0) break; 45 max_flow += plus; 46 } 47 return max_flow; 48 } 49 50 int main(){ 51 int t1,t2,t3; 52 while(scanf("%d%d",&n,&m) != EOF){ 53 memset(c,0,sizeof(c)); 54 for(int i = 1; i <= n; ++i){ 55 scanf("%d%d%d",&t1,&t2,&t3); 56 c[t1][t2] += t3; 57 } 58 printf("%d\n",FF()); 59 } 60 return 0; 61 }
Dinic:
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <stack> 9 #include <queue> 10 #include <iostream> 11 #include <algorithm> 12 using namespace std; 13 #define lp (p << 1) 14 #define rp (p << 1|1) 15 #define getmid(l,r) (l + (r - l) / 2) 16 #define MP(a,b) make_pair(a,b) 17 typedef long long ll; 18 typedef unsigned long long ull; 19 const int INF = 1 << 30; 20 const int maxn = 210; 21 22 int c[maxn][maxn],n,m,lev[maxn]; 23 int Q[maxn],head,rear; 24 25 void Bfs(){ 26 memset(lev,-1,sizeof(lev)); 27 lev[1] = 0; 28 Q[head = rear = 1] = 1; 29 while(head <= rear){ 30 int x = Q[head++]; 31 for(int i = 1; i <= m; ++i) if(lev[i] < 0 && c[x][i] > 0){ 32 lev[i] = lev[x] + 1; 33 Q[++rear] = i; 34 } 35 } 36 } 37 38 int Dfs(int p,int minc){ 39 if(p == m) return minc; 40 for(int i = 1; i <= m; ++i) if(lev[i] > lev[p] && c[p][i] > 0){ 41 int d = Dfs(i,min(c[p][i],minc)); 42 if(d > 0){ 43 c[p][i] -= d; 44 c[i][p] += d; 45 return d; 46 } 47 } 48 return 0; 49 } 50 51 52 int Dinic(){ 53 int max_flow = 0,plus; 54 while(1){ 55 Bfs(); 56 if(lev[m] < 0) break; 57 while((plus = Dfs(1,INF)) > 0) max_flow += plus; 58 } 59 return max_flow; 60 } 61 62 int main(){ 63 int t1,t2,t3; 64 while(scanf("%d%d",&n,&m) != EOF){ 65 memset(c,0,sizeof(c)); 66 for(int i = 1; i <= n; ++i){ 67 scanf("%d%d%d",&t1,&t2,&t3); 68 c[t1][t2] += t3; 69 } 70 printf("%d\n",Dinic()); 71 } 72 return 0; 73 }