summaryrefslogtreecommitdiff
path: root/graph
diff options
context:
space:
mode:
authorYidi <noob999noob999@gmail.com>2024-03-22 12:18:40 +0100
committerYidi <noob999noob999@gmail.com>2024-03-22 12:18:40 +0100
commit188120837921f37ffc5c63906070cfe5f1ef601a (patch)
treeb7778c7f0d17112b239931a6fecd8d89bf6fb2f7 /graph
parent5a6e689ffb206aab782102224fa64c6349c44aae (diff)
same interface as dinic + delete one push relabel
Diffstat (limited to 'graph')
-rw-r--r--graph/pushRelabel.cpp151
-rw-r--r--graph/pushRelabel2.cpp66
2 files changed, 53 insertions, 164 deletions
diff --git a/graph/pushRelabel.cpp b/graph/pushRelabel.cpp
index 52ba8b1..904aec6 100644
--- a/graph/pushRelabel.cpp
+++ b/graph/pushRelabel.cpp
@@ -1,109 +1,64 @@
-constexpr ll inf = 1ll<<60;
-
struct Edge {
- int from, to;
+ int to, rev;
ll f, c;
};
-vector<Edge> edges;
-vector<vector<int>> adj, llist;
-vector<int> height, ccount, que;
-vector<ll> excess;
-vector<list<int>> dlist;
-vector<list<int>::iterator> iter;
-int highest, highestActive;
-
-void addEdge(int from, int to, ll c) {
- adj[from].push_back(sz(edges));
- edges.push_back({from, to, 0, c});
- adj[to].push_back(sz(edges));
- edges.push_back({to, from, 0, 0});
-}
+vector<vector<Edge>> adj;
+vector<vector<int>> hs;
+vector<ll> ec;
+vector<int> cur, H;
-void globalRelabel(int n, int t) {
- height.assign(n, n);
- height[t] = 0;
- ccount.assign(n, 0);
- que.assign(n+1, 0);
- int qh = 0, qt = 0;
- for (que[qt++] = t; qh < qt;) {
- int v = que[qh++], h = height[v] + 1;
- for (int id : adj[v]) {
- if (height[edges[id].to] == n && edges[id ^ 1].c - edges[id ^ 1].f > 0) {
- ccount[height[edges[id].to] = h]++;
- que[qt++] = edges[id].to;
- }}}
- llist.assign(n+1, {});
- dlist.assign(n+1, {});
- for (int v = 0; v < n; v++) {
- if (height[v] < n) {
- iter[v] = dlist[height[v]].insert(dlist[height[v]].begin(), v);
- if (excess[v] > 0) llist[height[v]].push_back(v);
- }}
- highest = highestActive = height[que[qt - 1]];
+void addEdge(int u, int v, ll c) {
+ adj[u].push_back({v, (int)sz(adj[v]), 0, c});
+ adj[v].push_back({u, (int)sz(adj[u])-1, 0, 0});
}
-void push(int v, int id) {
- int u = edges[id].to;
- ll df = min(excess[v], edges[id].c - edges[id].f);
- edges[id].f += df;
- edges[id^1].f -= df;
- excess[v] -= df;
- excess[u] += df;
- if (0 < excess[u] && excess[u] <= df) llist[height[u]].push_back(u);
+void addFlow(Edge& e, ll f) {
+ if (ec[e.to] == 0 && f > 0)
+ hs[H[e.to]].push_back(e.to);
+ e.f += f;
+ adj[e.to][e.rev].f -= f;
+ ec[e.to] += f;
+ ec[adj[e.to][e.rev].to] -= f;
}
-void discharge(int n, int v) {
- int nh = n;
- for (int id : adj[v]) {
- if (edges[id].c - edges[id].f > 0) {
- if (height[v] == height[edges[id].to] + 1) {
- push(v, id);
- if (!excess[v]) return;
- } else {
- nh = min(nh, height[edges[id].to] + 1);
- }}}
- int h = height[v];
- if (ccount[h] == 1) {
- for (int i = h; i <= highest; i++) {
- for (auto p : dlist[i]) --ccount[height[p]], height[p] = n;
- dlist[i].clear();
- }
- highest = h - 1;
- } else {
- --ccount[h], iter[v] = dlist[h].erase(iter[v]), height[v] = nh;
- if (nh == n) return;
- ++ccount[nh], iter[v] = dlist[nh].insert(dlist[nh].begin(), v);
- highest = max(highest, highestActive = nh);
- llist[nh].push_back(v);
-}}
-
ll maxFlow(int s, int t) {
int n = sz(adj);
- llist.assign(n + 1, {});
- dlist.assign(n + 1, {});
- highestActive = highest = 0;
- height.assign(n, 0);
- height[s] = n;
- iter.resize(n);
- for (int v = 0; v < n; v++) {
- if (v != s) iter[v] = dlist[height[v]].insert(dlist[height[v]].begin(), v);
- }
- ccount.assign(n, 0);
- ccount[0] = n-1;
- excess.assign(n, 0);
- excess[s] = inf;
- excess[t] = -inf;
- for (int id : adj[s]) push(s, id);
- globalRelabel(n, t);
- while (highestActive >= 0) {
- if (llist[highestActive].empty()) {
- highestActive--;
- continue;
- }
- int v = llist[highestActive].back();
- llist[highestActive].pop_back();
- discharge(n, v);
- }
- return excess[t] + inf;
-}
+ 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 (Edge& e : adj[s]) addFlow(e, e.c);
+ for (int hi = 0;;) {
+ while (hs[hi].empty()) if (!hi--) return -ec[s];
+ int v = hs[hi].back();
+ hs[hi].pop_back();
+ while (ec[v] > 0) {
+ if (cur[v] == sz(adj[v])) {
+ H[v] = 2*n;
+ for (int i = 0; i < sz(adj[v]); i++) {
+ Edge& e = adj[v][i];
+ if (e.c - e.f > 0 &&
+ H[v] > H[e.to] + 1) {
+ H[v] = H[e.to] + 1;
+ cur[v] = i;
+ }}
+ co[H[v]]++;
+ 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[v];
+ } else {
+ Edge& e = adj[v][cur[v]];
+ if (e.c - e.f > 0 && H[v] == H[e.to] + 1) {
+ addFlow(adj[v][cur[v]], min(ec[v], e.c - e.f));
+ } else {
+ cur[v]++;
+}}}}}
diff --git a/graph/pushRelabel2.cpp b/graph/pushRelabel2.cpp
deleted file mode 100644
index 7d7defd..0000000
--- a/graph/pushRelabel2.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-struct Edge {
- int from, to;
- ll f, c;
-};
-
-vector<Edge> edges;
-vector<vector<int>> adj, hs;
-vector<ll> ec;
-vector<int> cur, H;
-
-void addEdge(int from, int to, ll c) {
- adj[from].push_back(sz(edges));
- edges.push_back({from, to, 0, c});
- adj[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(adj);
- 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 : adj[s]) addFlow(id, edges[id].c);
- for (int hi = 0;;) {
- while (hs[hi].empty()) if (!hi--) return -ec[s];
- int v = hs[hi].back();
- hs[hi].pop_back();
- while (ec[v] > 0) {
- if (cur[v] == sz(adj[v])) {
- H[v] = 2*n;
- for (int i = 0; i < sz(adj[v]); i++) {
- int id = adj[v][i];
- if (edges[id].c - edges[id].f > 0 &&
- H[v] > H[edges[id].to] + 1) {
- H[v] = H[edges[id].to] + 1;
- cur[v] = i;
- }}
- co[H[v]]++;
- 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[v];
- } else {
- auto e = edges[adj[v][cur[v]]];
- if (e.c - e.f > 0 && H[v] == H[e.to] + 1) {
- addFlow(adj[v][cur[v]], min(ec[v], e.c - e.f));
- } else {
- cur[v]++;
-}}}}}