Chapter 40: Graph Matchings and Assignment
40.03Intermediate / Advanced2 topics14 min1 interactive animation

Konig's theorem

König's theorem says that in a bipartite graph the size of a maximum matching equals the size of a minimum vertex cover. The proof is constructive: one alternating BFS from the free left vertices turns a maximum matching into a minimum cover.

Learning goals

  • State König's theorem
  • Follow the proof that the construction yields a cover of matching size
  • Build the cover with an alternating BFS
  • Use the theorem to get minimum covers and maximum independent sets

Prerequisites

Bipartite matching (Lesson 40.02)BFS

Two optimisation problems, “pair as many vertices as possible” and “watch every edge with as few vertices as possible”, look different, yet in bipartite graphs they have the same answer. Solving one solves the other, and the proof shows how to extract the second solution for free.

40.03.1

Maximum matching equals minimum vertex cover in bipartite graph

**König's theorem:** in every bipartite graph, the size of a maximum matching equals the size of a minimum vertex cover. One direction is the weak duality from the previous lesson (cover ≥ matching). The other direction needs a construction of a cover that is no larger than the matching.

Take a maximum matching M. Let Z be the set of vertices reachable from the free left vertices by **alternating paths** (non-matching edges from left to right, matching edges from right to left). Define the cover K = (Left \ Z) ∪ (Right ∩ Z): the left vertices the search did **not** reach, plus the right vertices it did reach. The following three facts prove the theorem.

First, every right vertex in Z is matched, because a free right vertex in Z would end an augmenting path, which cannot exist when M is maximum. Second, each matching edge has exactly one end in K: if its left end is reached, its right end was the way in (so the right end is in K and the left is not); if its left end is not reached, the right end cannot be reached either (it would pull its mate in), so the left end is the only cover vertex. Hence |K| = |M|. Third, K covers every edge: an edge from a reached left vertex always leads to a reached right vertex, so every edge has either an unreached left end or a reached right end.

  • Free left vertices are in Z by definition, so they are never in the cover.
  • Free right vertices are never in Z, so they are never in the cover either.
  • The cover has one vertex for each matching edge: that is why it is minimum.
Java
1// coverL / coverR flag the cover vertices on each side; true when the cover is valid and as large as the matching
2static boolean konigHolds(int[][] edges, boolean[] coverL, boolean[] coverR, int matchingSize) {
3 int size = 0;
4 for (boolean b : coverL) if (b) size++;
5 for (boolean b : coverR) if (b) size++;
6 for (int[] e : edges) if (!coverL[e[0]] && !coverR[e[1]]) return false; // edge {leftVertex, rightVertex}
7 return size == matchingSize;
8}
40.03.2

Construct cover from alternating BFS

The algorithm has three steps after the maximum matching is known. **(1)** Mark every free left vertex as reached and queue it. **(2)** Pop a left vertex u; for each neighbour v that has not been reached, mark v reached and, if v is matched, mark its mate w reached and queue it. **(3)** Output the left vertices that were **not** reached and the right vertices that **were** reached.

The BFS looks at each edge at most once, so the construction costs O(V + E) on top of the matching. Use the animation: the “Workers and jobs” preset has maximum matching 3. The only free left vertex is 3. The search reaches right vertex 0′ from it, steps back along the matching edge to 0′'s mate, left vertex 1, and finds nothing new from there. The reached set is {3, 1} on the left and {0′} on the right, so the cover is the unreached left vertices 0 and 2 plus the reached right vertex 0′: three vertices for a matching of three edges.

Two by-products come for free. The vertices **outside** the cover form a maximum independent set, and the complement of the cover on each side tells you which workers and jobs are in the bottleneck that prevents a perfect matching, the same bottleneck Hall's theorem describes.

StepCostResult
Maximum matching (Hopcroft-Karp)O(E · √V)matchL, matchR
Alternating BFS from free left verticesO(V + E)reached sets
Cover = unreached left + reached rightO(V)minimum vertex cover
Independent set = the complementO(V)maximum independent set
Java
1static boolean[][] minVertexCover(int left, int right, List<Integer>[] adj, int[] matchL, int[] matchR) {
2 boolean[] visL = new boolean[left], visR = new boolean[right];
3 Deque<Integer> queue = new ArrayDeque<>();
4 for (int u = 0; u < left; u++) if (matchL[u] == -1) { visL[u] = true; queue.add(u); } // start at every free left vertex
5 while (!queue.isEmpty()) {
6 int u = queue.poll();
7 for (int v : adj[u]) { // left to right: any edge (the matching edge of u is already visited)
8 if (visR[v]) continue;
9 visR[v] = true;
10 int w = matchR[v]; // right to left: only along the matching edge
11 if (w != -1 && !visL[w]) { visL[w] = true; queue.add(w); }
12 }
13 }
14 boolean[] coverL = new boolean[left], coverR = new boolean[right];
15 for (int u = 0; u < left; u++) coverL[u] = !visL[u]; // left vertices the search did NOT reach
16 for (int v = 0; v < right; v++) coverR[v] = visR[v]; // right vertices the search reached
17 return new boolean[][]{coverL, coverR};
18}

Worst

O(V + E) after the matching is known

Space

O(V)

König's theorem: minimum vertex cover from a maximum matching

Interactive · edit the input

Your input

Try

reached vertices are highlighted; green edges are matched · 8 vertices · 6 edges

0
1
2
3

free

0′
1′
2′
3′

free

In the vertex coverReached, not in the coverMatched edgeEdge used by the search

left vertices (cover = not reached)

0
1
2
3

right vertices (cover = reached)

0′
1′
2′
3′

mate of each left vertex

1′0
0′1
2′2
free3

mate of each right vertex

10′
01′
22′
free3′
Setup

The graph already has a maximum matching of size 3 (green edges; found as in the previous lesson). König's construction turns it into a vertex cover of exactly that size.

Step 1 / 6
Java
1static boolean[][] minVertexCover(int left, int right, List<Integer>[] adj, int[] matchL, int[] matchR) {
2 boolean[] visL = new boolean[left], visR = new boolean[right];
3 Deque<Integer> queue = new ArrayDeque<>();
4 for (int u = 0; u < left; u++) if (matchL[u] == -1) { visL[u] = true; queue.add(u); } // start at every free left vertex
5 while (!queue.isEmpty()) {
6 int u = queue.poll();
7 for (int v : adj[u]) { // left to right: any edge (the matching edge of u is already visited)
8 if (visR[v]) continue;
9 visR[v] = true;
10 int w = matchR[v]; // right to left: only along the matching edge
11 if (w != -1 && !visL[w]) { visL[w] = true; queue.add(w); }
12 }
13 }
14 boolean[] coverL = new boolean[left], coverR = new boolean[right];
15 for (int u = 0; u < left; u++) coverL[u] = !visL[u]; // left vertices the search did NOT reach
16 for (int v = 0; v < right; v++) coverR[v] = visR[v]; // right vertices the search reached
17 return new boolean[][]{coverL, coverR};
18}

Live state

0 left reached0 right reached

matching

3

left

4

right

4

No condition evaluated on this step
Execution trace (dry run table)Show 6 steps
StepLineStateWhat happens
1L1matching=3 left=4 right=4The graph already has a maximum matching of size 3 (green edges; found as in the previous lesson). König's construction turns it into a vertex cover of exactly that size.
2L4free_left=3Start the alternating search at every free left vertex: 3.
3L10u=3 reached=0′From 3 reach 0′ by edges; from each matched right vertex step back along its matching edge to its partner.
4L10u=1 reached=none1 has no unreached right neighbour.
5L15cover=0 2 0′ size=3Cover = left vertices not reached + right vertices reached = {0, 2, 0′}, 3 vertices.
6L17return=3 matching=3 uncovered_edges=0 cover=0 2 0′Every edge has a covered end (uncovered edges: 0) and the cover has 3 vertices, the same as the matching size 3. Any cover needs at least one vertex per matching edge, so this one is minimum.

Practice ladder

Now try it yourself

Easy

  • Is Graph Bipartite?

Medium

  • Possible Bipartition

Advanced

  • Maximum Students Taking Exam

Key takeaways

  • In a bipartite graph, maximum matching = minimum vertex cover (König).
  • Cover = left vertices not reached + right vertices reached by an alternating BFS from the free left vertices.
  • The complement of the cover is a maximum independent set; matching size n − that size is a consequence.