Skip to content

Commit 2f95c7a

Browse files
committed
feat: update to new kactl hopcroft_karp
1 parent 43e065f commit 2f95c7a

1 file changed

Lines changed: 22 additions & 42 deletions

File tree

lib/flow/hopcroft_karp.h

Lines changed: 22 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,29 @@
11
#include "../template.h"
22
/* -
33
name = "Hopcroft Karp"
4+
source = "https://github.com/kth-competitive-programming/kactl/blob/main/content/graph/HopcroftKarp.h"
45
[info]
5-
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` 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, or `-1` if it's not matched."
6-
usage = "`vi btoa(m, -1); hopcroftKarp(g, btoa);`"
6+
description = "Fast bipartite matching algorithm. Graph $g$ should be a list 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."
7+
usage = "`vi r(m, -1); hopcroftKarp(g, r);`"
78
time = "$O\\(sqrt(V) E\\)$"
89
- */
9-
bool dfs(int a, int L, vec<vi>& g, vi& btoa, vi& A, vi& B) {
10-
if (A[a] != L) return 0;
11-
A[a] = -1;
12-
for (int b : g[a]) if (B[b] == L + 1) {
13-
B[b] = 0;
14-
if (btoa[b] == -1 || dfs(btoa[b], L + 1, g, btoa, A, B))
15-
return btoa[b] = a, 1;
16-
}
17-
return 0;
18-
}
19-
int hopcroftKarp(vec<vi>& g, vi& btoa) {
20-
int res = 0;
21-
vi A(g.size()), B(btoa.size()), cur, next;
22-
for (;;) {
23-
fill(all(A), 0);
24-
fill(all(B), 0);
25-
cur.clear();
26-
for (int a : btoa) if(a != -1) A[a] = -1;
27-
rep(a,0,sz(g)) if(A[a] == 0) cur.push_back(a);
28-
for (int lay = 1;; lay++) {
29-
bool islast = 0;
30-
next.clear();
31-
for (int a : cur) for (int b : g[a]) {
32-
if (btoa[b] == -1) {
33-
B[b] = lay;
34-
islast = 1;
35-
}
36-
else if (btoa[b] != a && !B[b]) {
37-
B[b] = lay;
38-
next.push_back(btoa[b]);
39-
}
40-
}
41-
if (islast) break;
42-
if (next.empty()) return res;
43-
for (int a : next) A[a] = lay;
44-
cur.swap(next);
45-
}
46-
rep(a,0,sz(g))
47-
res += dfs(a, 0, g, btoa, A, B);
48-
}
10+
int hopcroftKarp(vector<vi>& g, vi& r) {
11+
int n = sz(g), res = 0;
12+
vi l(n, -1), q(n), d(n);
13+
auto dfs = [&](auto f, int u) -> bool {
14+
int t = exchange(d[u], 0) + 1;
15+
for (int v : g[u])
16+
if (r[v] == -1 || (d[r[v]] == t && f(f, r[v])))
17+
return l[u] = v, r[v] = u, 1;
18+
return 0;
19+
};
20+
for (int t = 0, f = 0;; t = f = 0, d.assign(n, 0)) {
21+
rep(i,0,n) if (l[i] == -1) q[t++] = i, d[i] = 1;
22+
rep(i,0,t) for (int v : g[q[i]]) {
23+
if (r[v] == -1) f = 1;
24+
else if (!d[r[v]]) d[r[v]] = d[q[i]] + 1, q[t++] = r[v];
25+
}
26+
if (!f) return res;
27+
rep(i,0,n) if (l[i] == -1) res += dfs(dfs, i);
28+
}
4929
}

0 commit comments

Comments
 (0)