#include "Graph.h" #include #include #include int Graph::checkBipart(std::vector& marks) const { marks.assign(n + 1, 0); auto nb = toSimpleAdj(); std::queue q; for (int s = 1; s <= n; ++s) { if (marks[s]) continue; marks[s] = 'A'; q.push(s); while (!q.empty()) { int u = q.front(); q.pop(); char opposite = (marks[u] == 'A') ? 'B' : 'A'; for (int v : nb[u]) { if (marks[v] == 0) { marks[v] = opposite; q.push(v); } else if (marks[v] == marks[u]) { return 0; } } } } return 1; } std::vector> Graph::getMaximumMatchingBipart() const { std::vector> matching; std::vector marks; if (!checkBipart(marks)) return matching; auto nb = toSimpleAdj(); std::vector match(n + 1, 0); // right vertex -> matched left vertex std::vector used(n + 1, 0); std::function augment = [&](int u) -> bool { used[u] = 1; for (int v : nb[u]) { if (marks[v] != 'B') continue; if (match[v] == 0 || (!used[match[v]] && augment(match[v]))) { match[v] = u; return true; } } return false; }; for (int u = 1; u <= n; ++u) { if (marks[u] != 'A') continue; std::fill(used.begin(), used.end(), (char)0); augment(u); } for (int v = 1; v <= n; ++v) if (match[v] != 0) matching.push_back({match[v], v}); return matching; }