class DSU: def __init__(self, n): self.p = list(range(n)) self.r = [0]*n # rank ~ tree height def find(self, x): while self.p[x] != x: self.p[x] = self.p[self.p[x]] # path compression (halving) x = self.p[x] return x def union(self, a, b): ra, rb = self.find(a), self.find(b) if ra == rb: return False # already connected -> would make cycle if self.r[ra] < self.r[rb]: ra, rb = rb, ra self.p[rb] = ra if self.r[ra] == self.r[rb]: self.r[ra] += 1 return Truedef kruskal(n, edges): # edges: list of (w,u,v) dsu = DSU(n); total = 0; mst = [] for w,u,v in sorted(edges): # WHY sort: process lightest first (greedy) if dsu.union(u,v): # WHY: union returns False if same component total += w; mst.append((u,v,w)) if len(mst) == n-1: break # WHY: a tree on n nodes needs exactly n-1 edges return total, mst
def prim(n, adj, start=0): # adj[u] = list of (w,v) import heapq visited = [False]*n pq = [(0, start)] # (edge weight to reach node, node) total = 0; cnt = 0 while pq and cnt < n: w, u = heapq.heappop(pq) # WHY heap: pop the globally cheapest frontier edge if visited[u]: continue # WHY: lazy deletion — stale heap entries skipped visited[u] = True; total += w; cnt += 1 for ew, v in adj[u]: if not visited[v]: heapq.heappush(pq, (ew, v)) # WHY: v is now reachable across the cut return total
Time: lazy heap O(ElogE); decrease-key / indexed heap ke saath O(ElogV);
Fibonacci heap ke saath O(E+VlogV).
MST weight =1+2+4=7. Step 3 skip kyun? Isse add karne par do already connected vertices join hote — cycle banti, jo kabhi MST mein nahi hoti.
Prim from 0: heap pops 0(w0) → push (1,1),(3,2),(5,3). Pop (1,1) → push (2,2). Pop (2,2) → push (4,3). Pop (4,3). Total =0+1+2+4=7. Same answer kyun? Dono cut property follow karte hain; MST weight unique hoti hai chahe tree na ho.
Recall Feynman: 12-saal ke bacche ko samjhao
Socho tum islands ko bridges se connect karna chahte ho, aur har bridge ki cost hoti hai. Tum chahte ho ki saare islands kam se kam paise mein jud jayein, aur koi bhi bekar bridge mat banao jo already jude islands ko loop back kare. Kruskal: saare possible bridges ko sabse saste se mehenge order mein dekho; ek hi banao agar woh do abhi-tak-nahi-jude groups ko jodta ho. Prim: ek island se shuru karo aur hamesha woh sabse sasta bridge add karo jo ek bilkul naye island tak pahunche. Dono ka total spend same minimum hoga.