From 76d705f0a26a1ccc5b72b5e9b15059b1fe469387 Mon Sep 17 00:00:00 2001 From: subcrip Date: Mon, 20 May 2024 13:31:59 +0800 Subject: [PATCH] Add graph/bounded_mcmf.cc Signed-off-by: subcrip --- graph/bounded_mcmf.cc | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 graph/bounded_mcmf.cc diff --git a/graph/bounded_mcmf.cc b/graph/bounded_mcmf.cc new file mode 100644 index 0000000..6014a62 --- /dev/null +++ b/graph/bounded_mcmf.cc @@ -0,0 +1,39 @@ +struct bounded_mcmf { + int n, m, S, T; + mcmf net; + ll sum; + vector fl; + vector init; + bounded_mcmf(int n, int m) : sum(0), n(n), m(m), S(0), T(n + 1), net(n + 1), fl(m), init(n + 1) {} + void add_edge(int from, int to, ll low, ll high, ll cost, int edge_id = -1) { + if (edge_id != -1) { + fl[edge_id] += low; + } + net.add_edge(from, to, high - low, cost, edge_id, -1); + init[to] += low, init[from] -= low; + } + optional>> run(int s, int t) { + for (int i = 1; i <= n; ++i) { + if (init[i] > 0) { + net.add_edge(S, i, init[i], 0, -1, -1); + sum += init[i]; + } else if (init[i] < 0) { + net.add_edge(i, T, -init[i], 0, -1, -1); + } + } + net.add_edge(t, s, INFLL, 0, -1, -1); + if (sum != net.run(S, T).first) { + return nullopt; + } else { + auto [res_flow, res_cost] = net.run(s, t); + for (int from = 1; from <= n; ++from) { + for (auto&& [to, cap, flow, cost, rev, mark] : net.edges[from]) { + if (mark != -1) { + fl[mark] = flow; + } + } + } + return {{res_flow, res_cost, fl}}; + } + } +};