From dcc79d0dae00bd3d4f8ce3850955a471cd504659 Mon Sep 17 00:00:00 2001 From: Bruno Freitas Tissei <bft15@inf.ufpr.br> Date: Sun, 3 Mar 2019 22:57:11 -0300 Subject: [PATCH] Add hopcroft karp algorithm Signed-off-by: Bruno Freitas Tissei <bft15@inf.ufpr.br> --- algorithms/graph/hopcroft_karp.cpp | 83 ++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 algorithms/graph/hopcroft_karp.cpp diff --git a/algorithms/graph/hopcroft_karp.cpp b/algorithms/graph/hopcroft_karp.cpp new file mode 100644 index 0000000..0969bde --- /dev/null +++ b/algorithms/graph/hopcroft_karp.cpp @@ -0,0 +1,83 @@ +/** + * Hopcroft-Karp + * + * Complexity (Time): O(E * sqrt(V)) + * Complexity (Space): O(V + E) + */ + +int dist[MAX]; +int matchL[MAX], matchR[MAX]; + +vector<int> graph[MAX]; + +// Builds an alternating level graph rooted at unmatched vertices in L +// using BFS, and returns whether there is an augmenting path in the graph +// or not +bool bfs(int n) { + queue<int> Q; + + // Add unmatched vertices in L to the queue + for (int l = 1; l <= n; ++l) + if (matchL[l] == 0) { + dist[l] = 0; + Q.push(l); + } else + dist[l] = inf; + + dist[0] = inf; + while (!Q.empty()) { + int l = Q.front(); Q.pop(); + + if (dist[l] < dist[0]) { + for (auto r : graph[l]) + if (dist[matchR[r]] == inf) { + dist[matchR[r]] = dist[l] + 1; + Q.push(matchR[r]); + } + } + } + + return (dist[0] != inf); +} + + +// Augments path starting in l if there is one, returns +// whether a path was augmented or not +bool dfs(int l) { + if (l == 0) + return true; + + for (auto r : graph[l]) { + + // The augmenting path has increasing dist, set by the BFS + if (dist[matchR[r]] == dist[l] + 1) + if (dfs(matchR[r])) { + matchR[r] = l; + matchL[l] = r; + return true; + } + } + + dist[l] = inf; + return false; +} + + +// Returns number of matched vertices on the left (matched edges) +int hopcroft_karp(int n) { + mset(matchL, 0); + mset(matchR, 0); + + int ans = 0; + + // While there is an augmenting path + while (bfs(n)) { + + // Augment the path when is possible + for (int l = 1; l <= n; ++l) + if (matchL[l] == 0 && dfs(l)) + ans++; + } + + return ans; +} -- GitLab