Minimum Spanning Trees: Kruskal & Prim
MST — Kruskal ও Prim
1. The MST Problem
Given a connected, undirected, weighted graph, an MST is a subset of edges that connects all vertices with the smallest total weight, using V − 1 edges. Used to wire up a campus network, design power grids, plan road systems, etc.
2. The Cut Property — Why Greedy Works
For any cut (partition of vertices into S and V\S), the lightest crossing edge is in some MST. This is the heart of every MST algorithm — Kruskal, Prim, Borůvka.
3. Kruskal — Sort + DSU
Sort all edges by weight. Walk through them; add each edge if its endpoints are in different components (use DSU from Module 22). Stop after V − 1 edges. O(E log E).
#include <bits/stdc++.h>
using namespace std;
struct DSU {
vector<int> p, r;
DSU(int n) : p(n), r(n, 0) { iota(p.begin(), p.end(), 0); }
int find(int x) { return p[x] == x ? x : p[x] = find(p[x]); }
bool unite(int a, int b) {
a = find(a); b = find(b);
if (a == b) return false;
if (r[a] < r[b]) swap(a, b);
p[b] = a;
if (r[a] == r[b]) r[a]++;
return true;
}
};
int main() {
int V = 4;
vector<tuple<int,int,int>> e = {{1,0,2},{2,1,3},{3,0,3},{4,2,3},{5,0,1}};
sort(e.begin(), e.end());
DSU dsu(V);
long long total = 0; int picked = 0;
for (auto [w, u, v] : e) {
if (dsu.unite(u, v)) {
total += w; picked++;
cout << "+ edge (" << u << "," << v << ") w=" << w << "\n";
if (picked == V - 1) break;
}
}
cout << "MST total = " << total;
}
4. Prim — Grow One Tree, Heap-Greedy
Start at any vertex. Maintain a min-heap of edges leaving the tree-so-far. Pop the lightest edge to a vertex outside the tree; add it; push its outgoing edges. Stop after V − 1 edges. O((V + E) log V) with a binary heap; O(E + V log V) with a Fibonacci heap.
#include <bits/stdc++.h>
using namespace std;
int main() {
int V = 4;
vector<vector<pair<int,int>>> adj(V);
vector<tuple<int,int,int>> e = {{0,1,5},{0,2,3},{0,3,3},{1,2,2},{2,3,4}};
for (auto [u, v, w] : e) { adj[u].push_back({v, w}); adj[v].push_back({u, w}); }
vector<bool> inTree(V, false);
priority_queue<tuple<int,int,int>, vector<tuple<int,int,int>>, greater<>> pq;
long long total = 0;
inTree[0] = true;
for (auto [v, w] : adj[0]) pq.push({w, 0, v});
while (!pq.empty()) {
auto [w, u, v] = pq.top(); pq.pop();
if (inTree[v]) continue;
inTree[v] = true; total += w;
cout << "+ edge (" << u << "," << v << ") w=" << w << "\n";
for (auto [n, ww] : adj[v]) if (!inTree[n]) pq.push({ww, v, n});
}
cout << "MST total = " << total;
}
5. Kruskal vs Prim & the MST Family
| Aspect | Kruskal | Prim |
|---|---|---|
| Approach | Sort edges, union-find | Grow tree from one vertex, heap |
| Time | O(E log E) | O((V+E) log V) |
| Best for | Sparse graphs, edge list given | Dense graphs |
| Implementation | ~20 lines (with DSU) | ~15 lines (with PQ) |
Borůvka: the third classic — runs O(log V) parallelisable phases. Less common in serial code but elegant and O(E log V).
MST uniqueness: if all edge weights are distinct, the MST is unique. With ties, multiple MSTs of the same total weight may exist.
6. Practice Problems
-
Compute the MST cost of the graph: edges (0,1,4), (0,2,3), (1,2,1), (1,3,2), (2,3,4), (3,4,2), (4,2,5).দেওয়া graph-এর MST cost বের করুন।
✨ Show Answer (উত্তর দেখুন)
Answer: sort by weight: (1,2)=1, (1,3)=2, (3,4)=2, (0,2)=3, (0,1)=4… Kruskal picks 1, 2, 2, 3 → total 8.
-
Min cost to connect all cities given pairwise costs (LeetCode 1135).পাইরওয়াইজ cost দিয়ে সব city connect — minimum cost।
✨ Show Answer (উত্তর দেখুন)
Approach: straight Kruskal. If after processing all edges fewer than V−1 are picked, return -1 (graph disconnected).
-
Second-best MST — modify Kruskal.Second-best MST।
✨ Show Answer (উত্তর দেখুন)
Approach: compute MST. For each non-MST edge e=(u,v) with weight w, find the max-weight edge on the u→v path in the MST (LCA + sparse table). Replacing it gives an alternative spanning tree; take the minimum increase.
-
MST on a 2D grid where edge weight is Manhattan distance.Manhattan distance grid-এ MST।
✨ Show Answer (উত্তর দেখুন)
Approach: the dense graph has C(n,2) edges. For n ≤ 1000, O(n²) Prim with a dense array (no PQ) is fastest. For n > 1000 use specialised geometric MST (Manhattan-MST in O(n log n)).
-
Given a Prim partial state {start = 0, picked edges (0,2,3)}, predict the next edge from edge list (0,1,5), (1,2,2), (2,3,4), (1,3,9).Prim-এর partial state দেখে পরবর্তী edge অনুমান করুন।
✨ Show Answer (উত্তর দেখুন)
Answer: tree currently contains {0, 2}. Crossing edges: (0,1)=5, (2,3)=4, (2,1)=2. Min is (2,1)=2 → add edge (2,1).
-
If two edges have equal weight, can you still get the same MST cost using Kruskal's tie-breaking? Justify.Equal weight হলে MST cost কি একই থাকে?
✨ Show Answer (উত্তর দেখুন)
Answer: the MST cost (sum) is unique even if the edge set is not. Different tie-break orders can produce different edge sets with the same total weight. Proof: contradiction with cut property.
Summary — Module 29
MST connects all vertices at minimum total weight. Kruskal: sort + DSU, O(E log E), best for sparse graphs. Prim: heap from one vertex, O((V+E) log V), best for dense. Both rest on the cut property, provable by exchange argument. Use DSU library from Module 22 — clean reuse.