poj1273 Drainage Ditches (最大流板子

网络流一直没学,来学一波网络流。

https://vjudge.net/problem/POJ-1273

题意:给定点数,边数,源点,汇点,每条边容量,求最大流。

解法:EK或dinic。

EK:每次增广用bfs选择一条从源到汇具有最少边数的增广路径,然后找出该路径容量最小的边,就是此次增加的流量,然后沿该路径增加反向边,同时修改每条边的容量,重复上述过程直到找不到增广路(即minFlow = 0)为止。

dinic: 每次bfs从源点到汇点分层(层数是源点到它最少要经过的边数),然后dfs从源点开始不断向下一层找增广路,碰到汇点说明找到一条,进行增广。然后回溯到点u(u是满足(u,v)容量为0的最上层节点)继续寻找增广路,如果回溯到源点且无法继续往下走dfs结束,然后对残余网络再分层,再dfs直到无法分层,算法结束。

 1 #include<iostream>
 2 #include<queue>
 3 #include<cstring>
 4 using namespace std;
 5 int G[300][300];
 6 int pre[300]; //前驱
 7 bool vis[300];
 8 int n,m; //1是源,m是汇
 9 
10 inline int solve(){
11     deque<int> q;
12     memset(pre,0,sizeof pre);
13     memset(vis,0,sizeof vis);
14     pre[1] = 0;
15     vis[1] = 1;
16     q.push_back(1);
17     bool find = false;
18     while(!q.empty()){
19         int v = q.front();
20         q.pop_front();
21         for(int i=1;i<=m;i++){
22             if(G[v][i]>0&&vis[i]==0){
23                 pre[i] = v;
24                 vis[i] = 1;
25                 if(i==m){
26                     find = true;
27                     q.clear();
28                     break;
29                 }
30                 else q.push_back(i);
31             }
32         }
33     }
34     if(!find) return 0;
35     int minFlow = 0x3f3f3f3f;
36     int v = m;
37     while(pre[v]){
38         minFlow = min(minFlow,G[pre[v]][v]);
39         v = pre[v];
40     }
41     v = m;
42     while(pre[v]){
43         G[pre[v]][v] -= minFlow;
44         G[v][pre[v]] += minFlow;
45         v = pre[v];
46     }
47     return minFlow;
48 }
49 
50 int main(){
51     while(cin>>n>>m){
52         memset(G,0,sizeof G);
53         for(int i=0;i<n;i++){
54             int s,e,c;
55             cin>>s>>e>>c;
56             G[s][e] += c;
57         }
58         int maxFlow = 0;
59         int aug;
60         while(aug=solve())
61             maxFlow += aug;
62         cout<<maxFlow<<endl;
63     }
64     return 0;
65 }
View Code
 1 #include<iostream>
 2 #include<queue>
 3 #include<cstring>
 4 using namespace std;
 5 const int inf = 0x3f3f3f3f;
 6 int G[300][300];
 7 bool vis[300];
 8 int Layer[300];
 9 int n,m; //1是源点,m是汇点
10 
11 inline bool countLayer(){
12     int layer = 0;
13     deque<int> q;
14     memset(Layer,0xff,sizeof Layer);
15     Layer[1] = 0;
16     q.push_back(1);
17     while(!q.empty()){
18         int v = q.front();
19         q.pop_front();
20         for(int j=1;j<=m;j++){
21             if(G[v][j]>0&&Layer[j]==-1){
22                 Layer[j] = Layer[v]+1;
23                 if(j==m) return true;
24                 else q.push_back(j);
25             }
26         }
27     }
28     return false;
29 }
30 
31 inline int dinic(){
32     int maxFlow = 0;
33     deque<int> q;
34     while(countLayer()){
35         q.push_back(1);
36         memset(vis,0,sizeof vis);
37         vis[1] = 1;
38         while(!q.empty()){
39             int nd = q.back();
40             if(nd==m){
41                 int minc = inf;
42                 int minc_vs;
43                 for(int i=1;i<q.size();i++){
44                     int vs = q[i-1];
45                     int ve = q[i];
46                     if(G[vs][ve]>0){
47                         if(minc>G[vs][ve]){
48                             minc = G[vs][ve];
49                             minc_vs = vs;
50                         }
51                     }
52                 }
53                 maxFlow += minc;
54                 for(int i=1;i<q.size();i++){
55                     int vs = q[i-1];
56                     int ve = q[i];
57                     G[vs][ve] -= minc;
58                     G[ve][vs] += minc;
59                 }
60                 while(!q.empty()&&q.back()!=minc_vs){
61                     vis[q.back()] = 0;
62                     q.pop_back();
63                 }
64             }
65             else {
66                 int i;
67                 for(i=1;i<=m;i++){
68                     if(G[nd][i]>0&&Layer[i]==Layer[nd]+1&&!vis[i]){
69                         vis[i] = 1;
70                         q.push_back(i);
71                         break;
72                     }
73                 }
74                 if(i>m) q.pop_back();
75             }
76         }
77     }
78     return maxFlow;
79 }
80 
81 int main(){
82     while(cin>>n>>m){
83         memset(G,0,sizeof G);
84         for(int i=0;i<n;i++){
85             int s,e,c;
86             cin>>s>>e>>c;
87             G[s][e] += c;
88         }
89         cout<<dinic()<<endl;
90     }
91     return 0;
92 }
View Code

 

posted @ 2019-08-15 14:31  时光已随风而逝~  阅读(182)  评论(0编辑  收藏  举报