Maximum matching in a non-bipartite graph. The augmenting-path idea from bipartite matching still applies (Berge’s theorem holds for all graphs), but odd cycles break the naive search.
Why odd cycles break things
In a bipartite graph, an alternating path’s parity at each vertex is determined by which side it is on. In a general graph, an odd cycle can be entered at one vertex and left with either parity — so a vertex may be reachable by both an even-length and an odd-length alternating path, and a plain BFS/DFS misses augmenting paths that require the “wrong” parity.
Blossoms
Edmonds’ insight: an odd cycle reachable by an even-length alternating path is a blossom. Contract it to a single vertex. The key lemma:
The graph has an augmenting path iff the graph with the blossom contracted has one.
So: search, contract blossoms as you find them, augment in the contracted graph, then expand back and lift the augmenting path. This is Edmonds’ Blossom algorithm — the first polynomial algorithm for general matching, and historically the paper where the notion of “polynomial time = efficient” was articulated.
The algorithms
| Algorithm | Time | Practicality |
|---|---|---|
| Blossom | the one to use — handles easily | |
| Micali-Vazirani | notoriously hard to implement correctly | |
| Gabow scaling (weighted) | theoretical | |
| Blossom V (Kolmogorov) | the standard weighted implementation in practice | |
| Tutte matrix (existence only) | randomized | 15 lines — see below |
Tutte matrix — the cheap trick
To decide whether a perfect matching exists (without constructing it), build the skew-symmetric Tutte matrix:
Tutte’s theorem: has a perfect matching iff as a polynomial.
Substitute random values mod a large prime and compute the determinant by Gaussian elimination. By Schwartz-Zippel the failure probability is — negligible. Rank even gives the size of the maximum matching.
// existence of a perfect matching, O(n^3), randomized
bool hasPerfectMatching(int n, vector<pair<int,int>>& edges, long long MOD) {
vector<vector<long long>> T(n, vector<long long>(n, 0));
for (auto [u, v] : edges) {
long long r = rng() % MOD;
T[u][v] = r; T[v][u] = MOD - r;
}
return rank(T, MOD) == n;
}Theory worth knowing
Tutte-Berge formula. The maximum matching size is
where counts components of odd size. It is the general-graph analogue of König’s theorem.
Tutte’s theorem. A perfect matching exists iff for every .
Petersen’s theorem. Every bridgeless cubic graph has a perfect matching.
Unlike the bipartite case, minimum vertex cover and maximum independent set remain NP-hard on general graphs — König’s equality is exactly what fails.
When you actually need it
General matching appears far less often than bipartite matching, and when it does the graph is usually small. Checklist:
- Is the graph secretly bipartite? Run a 2-colouring first — many “general” graphs in problems are bipartite by construction.
- Do you only need existence or the size? Use the Tutte matrix.
- Do you need the actual matching, unweighted? Blossom.
- Weighted? Blossom V, or model it as min-cost flow if the graph turns out bipartite.
See also: Blossom Algorithm · Bipartite Matching · Determinant