MST — Greedy Lens
Imagine you're a city planner connecting 10 remote towns with roads. Each possible road has a construction cost. You want every town connected to every other (directly or via other towns), and you want to spend as little total money as possible. What do you do?
Simple rule: always build the cheapest road that doesn't create a loop. A loop would mean you're paying for a redundant connection. Keep going until all towns are linked. That gives you the Minimum Spanning Tree — the cheapest possible network.
What Is a Spanning Tree?
A spanning tree of a connected graph with V vertices uses exactly V − 1 edges and connects all vertices with no cycles. The minimum spanning tree (MST) is the spanning tree with the lowest total edge weight. It's unique when all edge weights are distinct.
The Cut Property — Why Greedy Is Correct
Both MST algorithms are justified by the same theorem: the cut property.
A cut is any partition of vertices into two non-empty groups S and V\S. The cut property states: the minimum-weight edge crossing any cut is always part of some MST.
Why? Suppose the lightest crossing edge e were not in the MST. The MST still connects S to V\S, so some other edge e' crosses the cut. But e' is heavier than e. Swap e' for e — you get a lighter spanning tree, contradicting minimality of the MST. Contradiction.
Both Kruskal's and Prim's are simply different ways of repeatedly applying the cut property.
Kruskal's Algorithm
1. Sort all edges by weight ascending.
2. Go through edges in order. For each edge (u, v):
• If u and v are in different components → add this edge (it's the lightest edge crossing the cut between their components).
• If u and v are already connected → skip (adding it creates a cycle).
3. Stop when V − 1 edges are added.
Cycle detection is the key sub-problem. Union-Find solves it in nearly \(O(1)\) per edge: check find(u) == find(v). If equal, skip. If not, add the edge and union(u, v).
Total: \(O(E \log E)\) for sorting — Union-Find operations are nearly free.
Prim's Algorithm
1. Start from any vertex. Put it in the growing tree T.
2. Maintain a min-heap of edges leaving T (one endpoint in T, one outside).
3. Repeatedly extract the lightest such edge (u, v) where v is not yet in T. Add v (and the edge) to T. Push v's outgoing edges into the heap.
4. Stop when all vertices are in T.
This applies the cut property with S = current tree T at every step. The lightest edge from T to the rest is always safe to add.
With a binary heap: \(O(E \log V)\). With a Fibonacci heap: \(O(E + V \log V)\) — but Fibonacci heaps are complex to implement.
When to Use Each
Kruskal's is simpler to code and shines on sparse graphs (E close to V). Prim's with an adjacency matrix is better for dense graphs (E close to \(V^2\)) since you avoid sorting all edges. In competitive programming, Kruskal's + Union-Find is the go-to for most MST problems.