标签:问题: size math 最大流 msu printf ret 增加 网络流
网络流主要解决三种问题:最大流、最小流和费用流。
最大流算法主要有三种:EK算法、Dinic算法、SAP算法。
本篇博客是关于Dinic算法的。最坏的情况下,Dinic算法将达到复杂度O(V2E)。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <queue> 5 #include <cstring> 6 7 using namespace std; 8 const int INF = 0x3f3f3f3f; 9 const int maxn = 200 + 10; 10 const int maxm = 200 + 10; 11 12 int n,m; 13 int l[maxn];//记录层数 14 int h[maxn];//链式前向星 15 int cur[maxn]; 16 int tot = 0; 17 18 struct edge 19 { 20 int to; 21 int c; 22 int next; 23 edge(int x = 0, int y = 0, int z = 0) : to(x), c(y), next(z) {} 24 }es[maxm*2];//记录边 注意是2倍 25 26 void add_edge(int u, int v, int c) 27 { 28 es[tot] = edge(v,c,h[u]); 29 h[u] = tot++; 30 } 31 32 bool bfs(int s, int t) 33 { 34 memset(l,0,sizeof(l)); 35 l[s] = 1; 36 queue <int> q; 37 q.push(s); 38 while(!q.empty()) 39 { 40 int u = q.front(); 41 q.pop(); 42 if(u == t) return true; 43 for(int i = h[u]; i != -1; i = es[i].next) 44 { 45 int v = es[i].to; 46 if(!l[v] && es[i].c) {l[v] = l[u] + 1; q.push(v);} 47 } 48 } 49 return false; 50 } 51 52 int dfs(int x, int t, int mf) 53 { 54 if(x == t) return mf; 55 int ret = 0; 56 for(int i = cur[x]; i != -1; i = es[i].next) 57 { 58 if(es[i].c && l[x] == l[es[i].to] - 1) 59 { 60 int f = dfs(es[i].to,t,min(es[i].c,mf - ret)); 61 es[i].c -= f; 62 es[i^1].c += f; 63 ret += f; 64 if(ret == mf) return ret; 65 } 66 } 67 return ret; 68 } 69 70 int dinic(int s, int t) 71 { 72 int ans = 0; 73 while(bfs(s,t)) 74 { 75 for(int i = 0; i <= n; i++) cur[i] = h[i]; 76 ans += dfs(s,t,INF); 77 } 78 return ans; 79 } 80 81 int main() 82 { 83 while(~scanf("%d%d",&n,&m)) 84 { 85 tot = 0; 86 memset(h,-1,sizeof(h)); 87 int u,v,c; 88 for(int i = 0; i < m; i++) 89 { 90 scanf("%d%d%d",&u,&v,&c); 91 add_edge(u,v,c); 92 add_edge(v,u,0);//增加反向边 93 } 94 int ans = dinic(1,n); 95 printf("%d\n",ans); 96 } 97 return 0; 98 }
标签:问题: size math 最大流 msu printf ret 增加 网络流
原文地址:https://www.cnblogs.com/St-Lovaer/p/11909174.html