|
| 1 | +/** |
| 2 | + * Dinic法による最大流 |
| 3 | + * |
| 4 | + * ほとんど蟻本そのまま |
| 5 | + * template引数のint Vは頂点数 |
| 6 | + * Edgeにはrevが必要 |
| 7 | + * --- |
| 8 | + * void add_edge(Graph<Edge> &g, int from, int to, int cap) { |
| 9 | + * g[from].push_back(Edge{to, cap, (int)g[to].size()}); |
| 10 | + * g[to].push_back(Edge{from, 0, (int)g[from].size()-1}); |
| 11 | + * } |
| 12 | + * --- |
| 13 | + */ |
| 14 | +template<class T> // Tは容量の型 |
| 15 | +struct MaxFlow { |
| 16 | + const T INF = TEN(9); |
| 17 | + |
| 18 | + int V; |
| 19 | + vector<int> level, iter; |
| 20 | + |
| 21 | + //gを破壊するので注意 |
| 22 | + template<class E> |
| 23 | + T exec(Graph<E> &g, int s, int t) { |
| 24 | + V = (int)g.size(); |
| 25 | + level.resize(V); |
| 26 | + iter.resize(V); |
| 27 | + T flow = 0; |
| 28 | + while (true) { |
| 29 | + bfs(g, s); |
| 30 | + if (level[t] < 0) return flow; |
| 31 | + fill_n(iter.begin(), V, 0); |
| 32 | + while (true) { |
| 33 | + T f = dfs(g, s, t, INF); |
| 34 | + if (!f) break; |
| 35 | + flow += f; |
| 36 | + } |
| 37 | + } |
| 38 | + } |
| 39 | + |
| 40 | + template<class E> |
| 41 | + void bfs(const Graph<E> &g, int s) { |
| 42 | + fill_n(level.begin(), V, -1); |
| 43 | + queue<int> que; |
| 44 | + level[s] = 0; |
| 45 | + que.push(s); |
| 46 | + while (!que.empty()) { |
| 47 | + int v = que.front(); que.pop(); |
| 48 | + for (E e: g[v]) { |
| 49 | + if (e.cap <= 0) continue; |
| 50 | + if (level[e.to] < 0) { |
| 51 | + level[e.to] = level[v] + 1; |
| 52 | + que.push(e.to); |
| 53 | + } |
| 54 | + } |
| 55 | + } |
| 56 | + } |
| 57 | + |
| 58 | + template<class E> |
| 59 | + T dfs(Graph<E> &g, int v, int t, T f) { |
| 60 | + if (v == t) return f; |
| 61 | + for (int &i = iter[v]; i < (int)g[v].size(); i++) { |
| 62 | + E &e = g[v][i]; |
| 63 | + if (e.cap <= 0) continue; |
| 64 | + if (level[v] < level[e.to]) { |
| 65 | + T d = dfs(g, e.to, t, min(f, e.cap)); |
| 66 | + if (d <= 0) continue; |
| 67 | + e.cap -= d; |
| 68 | + g[e.to][e.rev].cap += d; |
| 69 | + return d; |
| 70 | + } |
| 71 | + } |
| 72 | + return 0; |
| 73 | + } |
| 74 | +}; |
0 commit comments