From e6ae5533476ddeb6c4d211d90fe2c426f41b7895 Mon Sep 17 00:00:00 2001 From: Brian G <130684373+azurerazor@users.noreply.github.com> Date: Mon, 20 Apr 2026 14:39:36 -0400 Subject: [PATCH 1/3] steal from kactl muahahaha --- content/graphs/hopcroftKarp.h | 75 +++++++++++------------------------ 1 file changed, 24 insertions(+), 51 deletions(-) diff --git a/content/graphs/hopcroftKarp.h b/content/graphs/hopcroftKarp.h index 83c9847a9..809cdc524 100644 --- a/content/graphs/hopcroftKarp.h +++ b/content/graphs/hopcroftKarp.h @@ -1,61 +1,34 @@ /** - * Author: Chen Xing - * Date: 2009-10-13 + * Author: Adam Soltan + * Date: 2026-01-13 * License: CC0 - * Source: N/A * Description: Fast bipartite matching algorithm. Graph $g$ should be a list - * of neighbors of the left partition, and $btoa$ should be a vector full of - * -1's of the same size as the right partition. Returns the size of - * the matching. $btoa[i]$ will be the match for vertex $i$ on the right side, + * of neighbors of the left partition, and $r$ should be a vector full of + * $-1$'s of the same size as the right partition. Returns the size of + * the matching. $r[i]$ will be the match for vertex $i$ on the right side, * or $-1$ if it's not matched. - * Usage: vi btoa(m, -1); hopcroftKarp(g, btoa); - * Time: O(\sqrt{V}E) - * Status: stress-tested by MinimumVertexCover, and tested on oldkattis.adkbipmatch and SPOJ:MATCHING + * Time: O(E \sqrt{V}) + * Status: stress-tested by MinimumVertexCover and tested on Library Checker */ #pragma once -bool dfs(int a, int L, vector& g, vi& btoa, vi& A, vi& B) { - if (A[a] != L) return 0; - A[a] = -1; - for (int b : g[a]) if (B[b] == L + 1) { - B[b] = 0; - if (btoa[b] == -1 || dfs(btoa[b], L + 1, g, btoa, A, B)) - return btoa[b] = a, 1; - } - return 0; -} - -int hopcroftKarp(vector& g, vi& btoa) { - int res = 0; - vi A(g.size()), B(btoa.size()), cur, next; - for (;;) { - fill(all(A), 0); - fill(all(B), 0); - /// Find the starting nodes for BFS (i.e. layer 0). - cur.clear(); - for (int a : btoa) if(a != -1) A[a] = -1; - rep(a,0,sz(g)) if(A[a] == 0) cur.push_back(a); - /// Find all layers using bfs. - for (int lay = 1;; lay++) { - bool islast = 0; - next.clear(); - for (int a : cur) for (int b : g[a]) { - if (btoa[b] == -1) { - B[b] = lay; - islast = 1; - } - else if (btoa[b] != a && !B[b]) { - B[b] = lay; - next.push_back(btoa[b]); - } - } - if (islast) break; - if (next.empty()) return res; - for (int a : next) A[a] = lay; - cur.swap(next); +int hopcroftKarp(vector& g, vi& r) { + int n = sz(g), res = 0; + vi l(n, -1), q(n), d(n); + auto dfs = [&](auto f, int u) -> bool { + int t = exchange(d[u], 0) + 1; + for (int v : g[u]) + if (r[v] == -1 || (d[r[v]] == t && f(f, r[v]))) + return l[u] = v, r[v] = u, 1; + return 0; + }; + for (int t = 0, f = 0;; t = f = 0, d.assign(n, 0)) { + rep(i,0,n) if (l[i] == -1) q[t++] = i, d[i] = 1; + rep(i,0,t) for (int v : g[q[i]]) { + if (r[v] == -1) f = 1; + else if (!d[r[v]]) d[r[v]] = d[q[i]] + 1, q[t++] = r[v]; } - /// Use DFS to scan for augmenting paths. - rep(a,0,sz(g)) - res += dfs(a, 0, g, btoa, A, B); + if (!f) return res; + rep(i,0,n) if (l[i] == -1) res += dfs(dfs, i); } } From 1cec2d592c85a0b5e4828836f990ae0dbb491044 Mon Sep 17 00:00:00 2001 From: Brian G <130684373+azurerazor@users.noreply.github.com> Date: Mon, 20 Apr 2026 14:40:17 -0400 Subject: [PATCH 2/3] Rename hopcroftKarp.h to HopcroftKarp.h --- content/graphs/{hopcroftKarp.h => HopcroftKarp.h} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename content/graphs/{hopcroftKarp.h => HopcroftKarp.h} (100%) diff --git a/content/graphs/hopcroftKarp.h b/content/graphs/HopcroftKarp.h similarity index 100% rename from content/graphs/hopcroftKarp.h rename to content/graphs/HopcroftKarp.h From 78e37a39602dde124242dc0f07c0653014fb67b7 Mon Sep 17 00:00:00 2001 From: Brian G <130684373+azurerazor@users.noreply.github.com> Date: Mon, 20 Apr 2026 14:41:23 -0400 Subject: [PATCH 3/3] bshdhif --- content/graphs/chapter.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/graphs/chapter.tex b/content/graphs/chapter.tex index db4a53742..15ea5cfb0 100644 --- a/content/graphs/chapter.tex +++ b/content/graphs/chapter.tex @@ -17,7 +17,7 @@ \section{Network flow} \kactlimport{MatroidIntersection.h} \section{Matching} - \kactlimport{hopcroftKarp.h} + \kactlimport{HopcroftKarp.h} \kactlimport{DFSMatching.h} \kactlimport{MinimumVertexCover.h} \kactlimport{WeightedMatching.h}