π£οΈ
Graphs (Advanced)
Kruskal + Union-Find Β· Prim
26. Minimum Spanning Tree
Find the minimum-weight tree that connects all vertices. Kruskal sorts edges then greedily adds non-cycle-forming ones via Union-Find; Prim grows the tree by always adding the cheapest border edge.
MSTKruskalPrimUnion-Find
Duration
β± ~1.5 hours
Level
π Advanced
Prerequisite
π― Graphs + heap
OUTCOME
Build an MST via Kruskal or Prim and reuse Union-Find for related problems.
What you'll learn
- 1Implement Union-Find with path compression and union by rank
- 2Implement Kruskal's algorithm
- 3Implement Prim's algorithm
Overview
An MST has V-1 edges and minimum total weight. Both Kruskal (E log E) and Prim ((V+E) log V) work. Union-Find (Disjoint Set Union) is a brilliant data structure for tracking connected components in O(Ξ±(N)) β O(1) per operation.
Core Concepts
1. Union-Find
python
class UF:
def __init__(self, n):
self.parent = list(range(n + 1))
self.rank = [0] * (n + 1)
def find(self, x):
while self.parent[x] != x:
self.parent[x] = self.parent[self.parent[x]] # path compression
x = self.parent[x]
return x
def union(self, x, y):
rx, ry = self.find(x), self.find(y)
if rx == ry: return False # same set
if self.rank[rx] < self.rank[ry]:
rx, ry = ry, rx
self.parent[ry] = rx
if self.rank[rx] == self.rank[ry]:
self.rank[rx] += 1
return True2. Kruskal's algorithm
python
def kruskal(n, edges):
"""edges: list of (weight, u, v)"""
edges.sort()
uf = UF(n)
total = 0
used = 0
for w, u, v in edges:
if uf.union(u, v):
total += w
used += 1
if used == n - 1: break
return total if used == n - 1 else -1 # disconnected3. Prim's algorithm
python
import heapq
def prim(n, adj):
visited = [False] * (n + 1)
heap = [(0, 1)]
total = 0
while heap:
w, u = heapq.heappop(heap)
if visited[u]: continue
visited[u] = True
total += w
for v, nw in adj[u]:
if not visited[v]:
heapq.heappush(heap, (nw, v))
return total4. Which to use
- Kruskal: simpler when edges are easy to list. O(E log E).
- Prim: better for dense graphs. O((V + E) log V).
- For competitive programming, Kruskal + Union-Find is often the path of least resistance.
Examples
Example 1 β src/01_union_find.py
Union-Find with path compression and union-by-rank.
Example 2 β src/02_kruskal.py
Kruskal MST β BOJ 1197.
Example 3 β src/03_prim.py
Prim MST with heapq.
Example 4 β src/04_cycle_detect.py
Detect a cycle in an undirected graph using Union-Find.
Common Mistakes
- Forgetting path compression in find() β degenerates to O(N) per op.
- Adding an edge to MST without checking it forms a cycle.
- Counting edges added β MST has exactly V-1.
- Not handling disconnected input (no MST possible).
Recap
- MST: V-1 edges, minimum total weight.
- Kruskal: sort edges + Union-Find.
- Prim: grow from a seed with a heap.
- Union-Find: O(Ξ±(N)) amortized per op.
Try It
- BOJ 1197 (MST).
- BOJ 4386 (Constellation).
- BOJ 1717 (Set operations) β pure Union-Find.
Example code / lecture materials
All lecture materials and example code are openly available on GitHub.
View on GitHub β