3.5.14 · HinglishGraphs

Minimum Spanning Tree — Kruskal's (Union-Find), Prim's (priority queue)

1,858 words8 min readRead in English

3.5.14 · Coding › Graphs


Woh ek theorem jo greed ko kaam karne deta hai


Kruskal's algorithm — "edges sort karo, agar cycle na bane toh add karo"

"Same component fast" kaise check karein? → Union-Find (DSU)

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 True
 
def 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

Time: (sort ka dominance) .


Prim's algorithm — "ek seed se ek tree ugao"

Sabse sasti crossing edge fast kaise milegi → min-heap (priority queue)

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 ; decrease-key / indexed heap ke saath ; Fibonacci heap ke saath .

Figure — Minimum Spanning Tree — Kruskal's (Union-Find), Prim's (priority queue)

Worked example (ek hi graph, dono algorithms)

Vertices . Edges: .

Kruskal:

Step Edge Action Kyun
1 (0,1,1) add sabse halki; 0,1 alag sets mein
2 (1,2,2) add 1,2 alag sets mein
3 (0,2,3) skip 0 aur 2 already same component mein → cycle
4 (2,3,4) add 2,3 alag sets mein → ab 3 edges (V−1) → ruko

MST weight . 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 (w0) → push (1,1),(3,2),(5,3). Pop (1,1) → push (2,2). Pop (2,2) → push (4,3). Pop (4,3). Total . 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.


Connections


Cut property kya guarantee karta hai?
Kisi bhi partition (cut) ke liye, minimum-weight crossing edge kisi na kisi MST mein hoti hai.
Ek cycle ki sabse halki edge MST mein kyun kabhi zaroorat nahi?
Isse remove karne par graph strictly/weakly kam weight ke saath connected rehta hai (cycle property).
Kruskal mein, Union-Find kya decide karta hai?
Kya dono endpoints already same component mein hain (toh edge add karne se cycle banegi).
Union-Find ke do optimizations aur unka effect?
Path compression + union by rank/size → near-constant α(V) amortized per op.
Kruskal ki time complexity aur kyun?
O(E log E), saari edges sort karne ka dominance.
Binary heap ke saath Prim ki time complexity?
Decrease-key ke saath O(E log V) (lazy deletion ke saath O(E log E)).
Prim ke lazy heap mein pop-then-skip-visited kyun kaam karta hai?
Stale entries ignore hoti hain (lazy deletion); pehli baar jab koi node pop hota hai woh apni sabse sasti crossing edge laata hai.
Kya MST algorithms negative edge weights ke saath kaam karte hain?
Haan — yeh sirf weights sort/compare karte hain; koi path relaxation nahi hoti.
Kruskal/Prim directed graphs par kyun apply nahi hote?
MST undirected graphs ke liye defined hai; directed case ko minimum arborescence (Edmonds) chahiye.
V vertices wale MST mein kitni edges hoti hain?
Exactly V−1.
Prim ke heap key aur Dijkstra ke beech kya fark hai?
Prim: cut cross karne wali single edge ka weight; Dijkstra: source se total path distance.
Kruskal vs Prim kab prefer karein?
Kruskal sparse/edge-list graphs ke liye; Prim dense/adjacency-list graphs ke liye.

Concept Map

minimize total weight

is a

avoids

lightest crossing edge is safe

justifies

justifies

cycle test via

near O of alpha V

grows tree from lightest edge

adds V-1 safe edges

Connected weighted undirected graph

Minimum Spanning Tree

Spanning tree V-1 edges no cycles

Cut property

Greedy correctness

Kruskal sort edges

Prim priority queue

Union-Find DSU

Path compression + union by rank