| 3 | struct cmp { bool operator()(int i, int j) const { |
| 4 | return d[i] == d[j] ? i < j : d[i] < d[j]; } }; |
| 5 | struct 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: |
nothing calls this directly
no outgoing calls
no test coverage detected