首页 > 代码库 > 最大流模板

最大流模板

最大流模板,用ISAP实现,时间复杂度$O(n^2m)$。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <vector>
  5 using namespace std;
  6 
  7 // maxflow::clear(int n);
  8 // maxflow::add_edge(int u, int v, int cap);
  9 // maxflow::solve(int s, int t);
 10 
 11 namespace maxflow {
 12   const int maxn = 500, maxm = 50000;
 13   const int inf = 0x3fffffff;
 14 
 15   struct edge {
 16     int v, cap;
 17   };
 18 
 19   int n, m;
 20   edge edges[maxm * 2];
 21   vector<int> g[maxn];
 22 
 23   void clear(int n_) {
 24     n = n_;
 25     m = 0;
 26     for (int i = 0; i < n; ++i) {
 27       g[i].clear();
 28     }
 29   }
 30 
 31   void add_edge(int u, int v, int cap) {
 32     g[u].push_back(m);
 33     edges[m++] = (edge){v, cap};
 34     g[v].push_back(m);
 35     edges[m++] = (edge){u, 0};
 36   }
 37 
 38   int h[maxn], cnth[maxn], iter[maxn];
 39   int pv[maxn], pe[maxn];
 40 
 41   int solve(int s, int t) {
 42     memset(h, 0, sizeof h);
 43     memset(cnth, 0, sizeof cnth);
 44     memset(iter, 0, sizeof iter);
 45     cnth[0] = n;
 46     pv[s] = s;
 47     int flow = 0, u = s;
 48     while (true) {
 49       if (u == t) {
 50     int add = inf;
 51     for (int v = t; v != s; v = pv[v]) {
 52       add = min(add, edges[pe[v]].cap);
 53     }
 54     for (int v = t; v != s; v = pv[v]) {
 55       edges[pe[v]].cap -= add;
 56       edges[pe[v] ^ 1].cap += add;
 57     }
 58     flow += add;
 59     u = s;
 60       }
 61       bool advanced = false;
 62       for (int &i = iter[u]; i < (int)g[u].size(); ++i) {
 63     edge &e = edges[g[u][i]];
 64     if (e.cap > 0 && h[u] == h[e.v] + 1) {
 65       advanced = true;
 66       pv[e.v] = u;
 67       pe[e.v] = g[u][i];
 68       u = e.v;
 69       break;
 70     }
 71       }
 72       if (!advanced) {
 73     int newh = n - 1;
 74     for (int i = iter[u] = 0; i < (int)g[u].size(); ++i) {
 75       edge &e = edges[g[u][i]];
 76       if (e.cap > 0) {
 77         newh = min(newh, h[e.v] + 1);
 78       }
 79     }
 80     if (--cnth[h[u]] == 0) {
 81       break;
 82     }
 83     h[u] = newh;
 84     ++cnth[newh];
 85     u = pv[u];
 86       }
 87     }
 88     return flow;
 89   }
 90 }
 91 
 92 // example
 93 
 94 int main(void) {
 95   int n, m, s, t;
 96   scanf("%d%d%d%d", &n, &m, &s, &t);
 97   --s; --t;
 98   maxflow::clear(n);
 99   for (int i = 0; i < m; ++i) {
100     int u, v, cap;
101     scanf("%d%d%d", &u, &v, &cap);
102     --u; --v;
103     maxflow::add_edge(u, v, cap);
104   }
105   int ans = maxflow::solve(s, t);
106   printf("%d\n", ans);
107 }

 

最大流模板