网络流一直没学,来学一波网络流。
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 }
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 }