summaryrefslogtreecommitdiff
path: root/graph/pushRelabel3.cpp
diff options
context:
space:
mode:
authormzuenni <michi.zuendorf@gmail.com>2022-06-27 17:19:28 +0200
committermzuenni <michi.zuendorf@gmail.com>2022-06-27 17:19:28 +0200
commit5ab8a5088b729a9953b8dff1b2a985dc8fb2098b (patch)
treeed40d6936c0e9eee40ba62751cbf99ecddbaddc2 /graph/pushRelabel3.cpp
parentadabbad9c51cf7cd3874bfde8eac1fbcf84fec10 (diff)
updated tcr
Diffstat (limited to 'graph/pushRelabel3.cpp')
-rw-r--r--graph/pushRelabel3.cpp66
1 files changed, 66 insertions, 0 deletions
diff --git a/graph/pushRelabel3.cpp b/graph/pushRelabel3.cpp
new file mode 100644
index 0000000..d4d2e67
--- /dev/null
+++ b/graph/pushRelabel3.cpp
@@ -0,0 +1,66 @@
+struct edge {
+ int from, to;
+ ll f, c;
+};
+
+vector<edge> edges;
+vector<vector<int>> adjlist, hs;
+vector<ll> ec;
+vector<int> cur, H;
+
+void addEdge(int from, int to, ll c) {
+ adjlist[from].push_back(sz(edges));
+ edges.push_back({from, to, 0, c});
+ adjlist[to].push_back(sz(edges));
+ edges.push_back({to, from, 0, 0});
+}
+
+void addFlow(int id, ll f) {
+ if (ec[edges[id].to] == 0 && f > 0)
+ hs[H[edges[id].to]].push_back(edges[id].to);
+ edges[id].f += f;
+ edges[id^1].f -= f;
+ ec[edges[id].to] += f;
+ ec[edges[id].from] -= f;
+}
+
+ll maxFlow(int s, int t) {
+ int n = sz(adjlist);
+ hs.assign(2*n, {});
+ ec.assign(n, 0);
+ cur.assign(n, 0);
+ H.assign(n, 0);
+ H[s] = n;
+ ec[t] = 1;//never set t to active...
+ vector<int> co(2*n);
+ co[0] = n - 1;
+ for (int id : adjlist[s]) addFlow(id, edges[id].c);
+ for (int hi = 0;;) {
+ while (hs[hi].empty()) if (!hi--) return -ec[s];
+ int u = hs[hi].back();
+ hs[hi].pop_back();
+ while (ec[u] > 0) {
+ if (cur[u] == sz(adjlist[u])) {
+ H[u] = 2*n;
+ for (int i = 0; i < sz(adjlist[u]); i++) {
+ int id = adjlist[u][i];
+ if (edges[id].c - edges[id].f > 0 &&
+ H[u] > H[edges[id].to] + 1) {
+ H[u] = H[edges[id].to] + 1;
+ cur[u] = i;
+ }}
+ co[H[u]]++;
+ if (!--co[hi] && hi < n) {
+ for (int i = 0; i < n; i++) {
+ if (hi < H[i] && H[i] < n) {
+ co[H[i]]--;
+ H[i] = n + 1;
+ }}}
+ hi = H[u];
+ } else {
+ auto e = edges[adjlist[u][cur[u]]];
+ if (e.c - e.f > 0 && H[u] == H[e.to] + 1) {
+ addFlow(adjlist[u][cur[u]], min(ec[u], e.c - e.f));
+ } else {
+ cur[u]++;
+}}}}}