From 57bb611284c40de7203759d184c8f8b8142ca752 Mon Sep 17 00:00:00 2001 From: Kyungmo Ku <46951576+Pentagon03@users.noreply.github.com> Date: Fri, 2 Aug 2024 23:13:35 +0900 Subject: [PATCH] Create MCMF.cpp --- Flow/MCMF.cpp | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 Flow/MCMF.cpp diff --git a/Flow/MCMF.cpp b/Flow/MCMF.cpp new file mode 100644 index 0000000..a266f13 --- /dev/null +++ b/Flow/MCMF.cpp @@ -0,0 +1,81 @@ +// hijkl2e, https://www.acmicpc.net/source/62155473 +template +class mcf_graph { +public: + using edge = tuple; + Cost mxcost{}; + mcf_graph(int V) : G(V), d(V), last(V), vst(V){ } + void add_edge(int u, int v, int cap, int cost, bool directed = true) { + G[u].push_back(E.size()); + E.push_back({v, cap, 0, cost}); + G[v].push_back(E.size()); + E.push_back({u, 0, 0, -cost}); + if (!directed) add_edge(v, u, cap, cost); + } + using pr = pair; + vector slope(int s, int t, Cost max_cost){ + mxcost = max_cost; + Cap mf{}; + vector ans({pr{mf, tcost}}); + while (spfa(s, t)) { + fill(last.begin(), last.end(), 0); + while (int f = dfs(s, t)) { + mf += f; + ans.push_back({mf, tcost}); + } + } + return ans; + } + pr flow(int s, int t, Cost max_cost) { + return slope(s, t, max_cost).back(); + } +private: + bool spfa(int s, int t) { + fill(d.begin(), d.end(), mxcost); + queue q; + d[s] = 0, vst[s] = true; + q.push(s); + while (q.size()) { + int u = q.front(); q.pop(); + vst[u] = false; + for (int idx : G[u]) { + auto &[v, cap, flow, cost] = E[idx]; + if (d[v] > d[u] + cost && flow < cap) { + d[v] = d[u] + cost; + if (!vst[v]) { + vst[v] = true; + q.push(v); + } + } + } + } + return d[t] < mxcost; + } + Cap dfs(int u, int t, int f = inf) { + if (u == t) { + return f; + } + vst[u] = true; + for (int &i = last[u]; i < G[u].size(); ++i) { + auto &[v, cap, flow, cost] = E[G[u][i]]; + if (!vst[v] && d[v] == d[u] + cost && flow < cap) { + if (Cap pushed = dfs(v, t, min(f, cap - flow))) { + tcost += pushed * cost; + flow += pushed; + auto &rflow = get<2>(E[G[u][i] ^ 1]); + rflow -= pushed; + vst[u] = false; + return pushed; + } + } + } + vst[u] = false; + return 0; + } + vector E; + vector> G; + vector d; + vector last; + vector vst; + Cost tcost{}; +};