-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathhopcroft_karp.cpp
63 lines (57 loc) · 1.28 KB
/
hopcroft_karp.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/*
Tested: SPOJ MATCHING
Complexity: O(m n^0.5)
*/
struct graph {
int L, R;
vector<vector<int>> adj;
graph(int L, int R) : L(L), R(R), adj(L + R) {}
void add_edge(int u, int v) {
adj[u].push_back(v + L);
adj[v + L].push_back(u);
}
int maximum_matching() {
vector<int> level(L), mate(L + R, -1);
function<bool(void)> levelize = [&]() {
queue<int> Q;
for (int u = 0; u < L; ++u) {
level[u] = -1;
if (mate[u] < 0) {
level[u] = 0;
Q.push(u);
}
}
while (!Q.empty()) {
int u = Q.front();
Q.pop();
for (int w : adj[u]) {
int v = mate[w];
if (v < 0)
return true;
if (level[v] < 0) {
level[v] = level[u] + 1;
Q.push(v);
}
}
}
return false;
};
function<bool(int)> augment = [&](int u) {
for (int w : adj[u]) {
int v = mate[w];
if (v < 0 || (level[v] > level[u] && augment(v))) {
mate[u] = w;
mate[w] = u;
return true;
}
}
return false;
};
int match = 0;
while (levelize())
for (int u = 0; u < L; ++u)
if (mate[u] < 0 && augment(u))
++match;
return match;
}
};