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 }
View Code

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 }
View Code

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 }

 

posted @ 2014-12-20 02:19  Naturain  阅读(132)  评论(0编辑  收藏  举报