Struktur data Union-Find dengan path compression dan union by rank untuk operasi near-constant time, serta Kruskal's algorithm untuk Minimum Spanning Tree dengan greedy edge selection.

Setelah di episode 19 kita membahas shortest path berbobot, pada episode ini kita membahas Minimum Spanning Tree (MST) — subset edge yang menghubungkan semua vertex dengan total bobot minimum tanpa siklik. Kita fokus pada Kruskal's algorithm yang menggunakan Union-Find — struktur data elegan yang mendukung operasi near-constant time.
Union-Find dan Kruskal adalah kombinasi powerful: Union-Find memungkinkan Kruskal memeriksa siklik secara efisien, menjadikan MST bisa diselesaikan dalam O(E log E) — sebagian besar waktu dihabiskan untuk mengurutkan edge.
Union-Find mendukung dua operasi:
class UnionFind:
def __init__(self, n):
self.parent = list(range(n))
self.rank = [0] * n
def find(self, x):
if self.parent[x] != x:
self.parent[x] = self.find(self.parent[x]) # path compression
return self.parent[x]
def union(self, x, y):
root_x = self.find(x)
root_y = self.find(y)
if root_x == root_y:
return False # sudah satu set
# Union by rank
if self.rank[root_x] < self.rank[root_y]:
self.parent[root_x] = root_y
elif self.rank[root_x] > self.rank[root_y]:
self.parent[root_y] = root_x
else:
self.parent[root_y] = root_x
self.rank[root_x] += 1
return TrueDua optimasi kunci yang menjadikan operasi near-constant:
Tanpa optimasi: O(n) per operasi. Dengan kedua optimasi: O(α(n)) per operasi, di mana α adalah inverse Ackermann function — hampir konstanta (maksimal 4 untuk input praktis).
Note
α(n) — inverse Ackermann — tumbuh sangat lambat: α(10^80) ≈ 4. Untuk semua input praktis, α(n) ≤ 4. Ini menjadikan Union-Find hampir secepat O(1) amortized — struktur data paling efisien yang pernah dianalisis.
Kruskal membangun MST dengan greedy: urutkan semua edge berdasarkan bobot, lalu tambahkan edge terkecil yang tidak membentuk siklik (dicek dengan Union-Find).
def kruskal_mst(edges, n):
"""edges: [(weight, u, v)]"""
edges.sort() # urutkan berdasarkan bobot
uf = UnionFind(n)
mst = []
total_weight = 0
for weight, u, v in edges:
if uf.union(u, v): # tidak siklik
mst.append((u, v, weight))
total_weight += weight
if len(mst) == n - 1:
break # MST punya n-1 edge
return mst, total_weightGreedy choice property: edge terkecil yang tidak membentuk siklik pasti ada di MST. Jika tidak, menggantinya dengan edge ini akan menghasilkan MST yang lebih ringan — kontradiksi.
| Metrik | Nilai |
|---|---|
| Time | O(E log E) — sorting + Union-Find |
| Space | O(V + E) |
| Best for | Sparse graphs |
Prim adalah alternatif MST: mulai dari satu vertex, terus tambahkan edge terkecil yang menghubungkan tree ke vertex di luar tree (seperti Dijkstra tetapi untuk MST).
| Kriteria | Kruskal | Prim |
|---|---|---|
| Pendekatan | Greedy edge | Grow tree |
| Data structure | Union-Find | Priority queue |
| Time | O(E log E) | O((V+E) log V) |
| Best for | Sparse | Dense |
| Parallel | Mudah | Sulit |
Tip
Kruskal lebih mudah diparalelkan karena setiap edge bisa diproses independen — cocok untuk distributed computing. Prim lebih efisien untuk dense graphs karena tidak perlu mengurutkan semua edge.
Implementasi Kruskal untuk MST pada road network sederhana (5-10 kota). Cetak MST edges dan total weight. Bandingkan hasil dengan Prim. Verifikasi bahwa MST menghubungkan semua vertex dengan n-1 edge dan total weight minimum.
Pada episode 20 ini, kalian telah memahami:
Di episode 21 selanjutnya kita akan membahas Network Flow (Pengenalan) — flow network, max-flow min-cut theorem, dan Edmonds-Karp algorithm. Sampai jumpa di episode 21!