MCPcopy Create free account
hub / github.com/SuprDewd/CompetitiveProgramming / flow_network

Class flow_network

code/graph/edmonds_karps_mcmf.cpp:5–49  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

3struct cmp { bool operator()(int i, int j) const {
4 return d[i] == d[j] ? i < j : d[i] < d[j]; } };
5struct flow_network {
6 struct edge { int v, nxt, cap, cost;
7 edge(int _v, int _cap, int _cost, int _nxt)
8 : v(_v), nxt(_nxt), cap(_cap), cost(_cost) { } };
9 int n; vi head; vector<edge> e, e_store;
10 flow_network(int _n) : n(_n), head(n,-1) { }
11 void reset() { e = e_store; }
12 void add_edge(int u, int v, int cost, int uv, int vu=0) {
13 e.push_back(edge(v, uv, cost, head[u]));
14 head[u] = (int)size(e)-1;
15 e.push_back(edge(u, vu, -cost, head[v]));
16 head[v] = (int)size(e)-1; }
17 ii min_cost_max_flow(int s, int t, bool res=true) {
18 e_store = e;
19 memset(pot, 0, n*sizeof(int));
20 rep(it,0,n-1) rep(i,0,size(e)) if (e[i].cap > 0)
21 pot[e[i].v] =
22 min(pot[e[i].v], pot[e[i^1].v] + e[i].cost);
23 int v, f = 0, c = 0;
24 while (true) {
25 memset(d, -1, n*sizeof(int));
26 memset(p, -1, n*sizeof(int));
27 set<int, cmp> q;
28 d[s] = 0; q.insert(s);
29 while (!q.empty()) {
30 int u = *q.begin();
31 q.erase(q.begin());
32 for (int i = head[u]; i != -1; i = e[i].nxt) {
33 if (e[i].cap == 0) continue;
34 int cd = d[u] + e[i].cost + pot[u] - pot[v = e[i].v];
35 if (d[v] == -1 || cd < d[v]) {
36 q.erase(v);
37 d[v] = cd; p[v] = i;
38 q.insert(v); } } }
39 if (p[t] == -1) break;
40 int at = p[t], x = INF;
41 while (at != -1)
42 x = min(x, e[at].cap), at = p[e[at^1].v];
43 at = p[t], f += x;
44 while (at != -1)
45 e[at].cap -= x, e[at^1].cap += x, at = p[e[at^1].v];
46 c += x * (d[t] + pot[t] - pot[s]);
47 rep(i,0,n) if (p[i] != -1) pot[i] += d[i]; }
48 if (res) reset();
49 return ii(f, c); } };
50// vim: cc=60 ts=2 sts=2 sw=2:

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected