首页 > 代码库 > 最小费用最大流模板

最小费用最大流模板

最小费用最大流模板,用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 }

 

最小费用最大流模板