最小费用最大流模板
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最小费用最大流模板相关的知识,希望对你有一定的参考价值。
最小费用最大流模板,用Dijkstra增广,时间复杂度$O(vm\log n)$,其中$v$是流量。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <vector> 5 #include <queue> 6 using namespace std; 7 8 typedef pair<int, int> pii; 9 10 // mcmf::clear(int n); 11 // mcmf::add_edge(int u, int v, int cap, int cost); 12 // mcmf::solve(int s, int t); 13 14 namespace mcmf { 15 const int maxn = 200, maxm = 1000; 16 const int inf = 0x3fffffff; 17 18 struct edge { 19 int v, cap, cost; 20 }; 21 22 int n, m; 23 edge edges[maxm * 2]; 24 vector<int> g[maxn]; 25 26 void clear(int n_) { 27 n = n_; 28 m = 0; 29 for (int i = 0; i < n; ++i) { 30 g[i].clear(); 31 } 32 } 33 34 void add_edge(int u, int v, int cap, int cost) { 35 g[u].push_back(m); 36 edges[m++] = (edge){v, cap, cost}; 37 g[v].push_back(m); 38 edges[m++] = (edge){u, 0, -cost}; 39 } 40 41 int h[maxn], dist[maxn]; 42 int pv[maxn], pe[maxn]; 43 44 pii solve(int s, int t) { 45 int flow = 0, cost = 0; 46 memset(h, 0, sizeof h); 47 while (true) { 48 fill(dist, dist + n, inf); 49 priority_queue<pii, vector<pii>, greater<pii> > q; 50 dist[s] = 0; 51 q.push(pii(0, s)); 52 while (!q.empty()) { 53 pii foo = q.top(); q.pop(); 54 int u = foo.second; 55 if (foo.first != dist[u]) { 56 continue; 57 } 58 for (int i = 0; i < (int)g[u].size(); ++i) { 59 edge &e = edges[g[u][i]]; 60 int newdist = dist[u] + e.cost + h[u] - h[e.v]; 61 if (e.cap > 0 && newdist < dist[e.v]) { 62 dist[e.v] = newdist; 63 pv[e.v] = u; 64 pe[e.v] = g[u][i]; 65 q.push(pii(newdist, e.v)); 66 } 67 } 68 } 69 if (dist[t] == inf) { 70 break; 71 } 72 for (int i = 0; i < n; ++i) { 73 h[i] = min(h[i] + dist[i], inf); 74 } 75 int add = inf; 76 for (int v = t; v != s; v = pv[v]) { 77 edge &e = edges[pe[v]]; 78 add = min(add, e.cap); 79 } 80 for (int v = t; v != s; v = pv[v]) { 81 edges[pe[v]].cap -= add; 82 edges[pe[v] ^ 1].cap += add; 83 } 84 flow += add; 85 cost += add * h[t]; 86 } 87 return pii(flow, cost); 88 } 89 } 90 91 int main(void) { 92 int n, m, s, t; 93 scanf("%d%d%d%d", &n, &m, &s, &t); 94 --s; --t; 95 mcmf::clear(n); 96 for (int i = 0; i < m; ++i) { 97 int u, v, cap, cost; 98 scanf("%d%d%d%d", &u, &v, &cap, &cost); 99 --u; --v; 100 mcmf::add_edge(u, v, cap, cost); 101 } 102 pii ans = mcmf::solve(s, t); 103 printf("%d %d\n", ans.first, ans.second); 104 }
以上是关于最小费用最大流模板的主要内容,如果未能解决你的问题,请参考以下文章