最大流 最小费用流模板
Posted hjmmm
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最大流 最小费用流模板相关的知识,希望对你有一定的参考价值。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <queue> 5 using namespace std; 6 const int INF = 0x3f3f3f3f; 7 const int N = 10005; 8 const int M = 100005; 9 struct type{ 10 int u, v, w, next; 11 }edge[M << 1]; 12 int head[N], cnt; 13 int dep[N], cur[N]; 14 int n, m, s, t, d; 15 void add(int x, int y, int z){ 16 edge[cnt].u = x; 17 edge[cnt].v = y; 18 edge[cnt].w = z; 19 edge[cnt].next = head[x]; 20 head[x] = cnt; 21 cnt++; 22 } 23 bool bfs(){ 24 int fro = 0; 25 queue<int> q; 26 q.push(s); 27 for(int i = 1; i <= n; i++) dep[i] = 0; 28 dep[s] = 1;//important!!!!! 29 while(!q.empty()){ 30 fro = q.front(); q.pop(); 31 for(int i = head[fro]; i != -1; i = edge[i].next){ 32 int vv = edge[i].v; 33 if(!dep[vv] && edge[i].w > 0){ 34 dep[vv] = dep[fro] + 1; 35 q.push(vv); 36 } 37 } 38 } 39 return dep[t] ? 1 : 0; 40 } 41 int dfs(int x, int rest){ 42 if(x == t || !rest) return rest; 43 for(int& i = cur[x]; i != -1; i = edge[i].next){//当前弧优化 44 int vv = edge[i].v, ww = edge[i].w; 45 if(dep[vv] != dep[x] + 1) continue; 46 d = dfs(vv, min(rest, ww)); 47 if(d > 0){ 48 edge[i].w -= d; 49 edge[i ^ 1].w += d; 50 return d; 51 } 52 } 53 return 0; 54 } 55 int dinic(){ 56 int ans = 0; 57 while(bfs()){ 58 for(int i = 1; i <= n; i++) cur[i] = head[i];//当前弧优化 59 if(d = dfs(s, INF)){ 60 ans += d; 61 } 62 } 63 return ans; 64 } 65 int main() { 66 int x, y, z; 67 scanf("%d%d%d%d", &n, &m, &s, &t); 68 for(int i = 1; i <= n; i++) head[i] = -1; 69 for(int i = 1; i <= m; i++){ 70 scanf("%d%d%d", &x, &y, &z); 71 add(x, y, z); 72 add(y, x, 0); 73 } 74 printf("%d", dinic()); 75 return 0; 76 }
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <queue> 5 using namespace std; 6 const int INF = 0x3f3f3f3f; 7 const int N = 5005; 8 const int M = 50005; 9 struct type{ 10 int u, v, w, f, next; 11 }edge[M << 1]; 12 struct type2{ 13 int f, cur, incf; 14 bool vis; 15 }ser[N]; 16 int head[N], cnt; 17 int n, m, s, t; 18 int max_flow, min_cost; 19 void add(int x, int y, int z, int zz){ 20 edge[cnt].u = x; 21 edge[cnt].v = y; 22 edge[cnt].w = z; 23 edge[cnt].f = zz; 24 edge[cnt].next = head[x]; 25 head[x] = cnt; 26 cnt++; 27 } 28 bool spfa(){ 29 for(int i = 1; i <= n; i++){ 30 ser[i].vis = 0; 31 ser[i].f = INF; 32 } 33 ser[s].f = 0; 34 ser[s].incf = INF; 35 int fro; 36 queue<int> q; 37 q.push(s); 38 while(!q.empty()){ 39 fro = q.front(); q.pop(); ser[fro].vis = 0; 40 for(int i = head[fro]; i != -1; i = edge[i].next){ 41 int vv = edge[i].v, ww = edge[i].w, ff = edge[i].f; 42 if(ww > 0 && ser[fro].f + ff < ser[vv].f){ 43 ser[vv].f = ser[fro].f + ff; 44 ser[vv].incf = min(ser[fro].incf, ww); 45 ser[vv].cur = i; 46 if(!ser[vv].vis){ 47 ser[vv].vis = 1; 48 q.push(vv); 49 } 50 } 51 } 52 } 53 return ser[t].f == INF ? 0 : 1; 54 } 55 void update(){ 56 int i = t, j; 57 while(i != s){ 58 j = ser[i].cur; 59 edge[j].w -= ser[t].incf; 60 edge[j ^ 1].w += ser[t].incf; 61 i = edge[j].u; 62 } 63 max_flow += ser[t].incf; 64 min_cost += ser[t].f * ser[t].incf; 65 } 66 void EK(){ 67 while(spfa()){ 68 update(); 69 } 70 } 71 int main() { 72 //freopen("testdata.in", "r", stdin); 73 //freopen("testdata.out", "w", stdout); 74 int x, y, z, zz; 75 scanf("%d%d%d%d", &n, &m, &s, &t); 76 for(int i = 1; i <= n; i++) head[i] = -1; 77 for(int i = 1; i <= m; i++){ 78 scanf("%d%d%d%d", &x, &y, &z, &zz); 79 add(x, y, z, zz); 80 add(y, x, 0, -zz); 81 } 82 EK(); 83 printf("%d %d ", max_flow, min_cost); 84 return 0; 85 }
以上是关于最大流 最小费用流模板的主要内容,如果未能解决你的问题,请参考以下文章