๐ฒ Minimum Spanning Tree (MST) โ Complete In-Depth Explanation
A **Minimum Spanning Tree (MST)** is a **subset of edges** in a **connected, weighted graph** that connects all vertices with the **minimum total edge weight** and **without forming cycles**.
๐ Why is MST Important?
- โ **Used in network design (telecommunication, electrical circuits, road networks).**
- ๐ก **Essential for clustering in machine learning.**
- ๐ **Forms the basis for algorithms like Approximate TSP.**
- ๐ **Efficient in constructing trees with minimal cost in weighted graphs.**
๐ Understanding MST with an Example
Given the following weighted graph:
2 3
A---B---C
| | |
1 | 4 | 6
| | |
D---E---F
5
The **Minimum Spanning Tree (MST)** would be:
2 3
A---B---C
|
1 |
|
D
๐น **Key Points**
- โ The MST must have exactly **V - 1 edges** (where V is the number of vertices).
- ๐ The MST must have the **minimum possible total weight**.
- ๐ There can be **multiple valid MSTs** for a given graph.
๐ Solution Approaches
๐ **1. Kruskalโs Algorithm (Greedy, O(E log E))**
Kruskalโs Algorithm sorts all edges by weight and adds them **one by one** while ensuring **no cycles are formed** (using Disjoint Set Union - DSU).
struct Edge {
int src, dest, weight;
};
struct Graph {
int V, E;
vector edges;
};
struct DSU {
vector parent, rank;
DSU(int n) {
parent.resize(n);
rank.resize(n, 0);
for (int i = 0; i < n; i++) parent[i] = i;
}
int find(int x) {
if (parent[x] != x) parent[x] = find(parent[x]);
return parent[x];
}
void unite(int x, int y) {
int rootX = find(x), rootY = find(y);
if (rootX != rootY) {
if (rank[rootX] > rank[rootY]) parent[rootY] = rootX;
else if (rank[rootX] < rank[rootY]) parent[rootX] = rootY;
else {
parent[rootY] = rootX;
rank[rootX]++;
}
}
}
};
void Kruskal(Graph &graph) {
sort(graph.edges.begin(), graph.edges.end(), [](Edge a, Edge b) {
return a.weight < b.weight;
});
DSU dsu(graph.V);
vector mst;
int mstCost = 0;
for (Edge e : graph.edges) {
if (dsu.find(e.src) != dsu.find(e.dest)) {
dsu.unite(e.src, e.dest);
mst.push_back(e);
mstCost += e.weight;
}
}
cout << "Minimum Spanning Tree Cost: " << mstCost << endl;
for (Edge e : mst) {
cout << e.src << " -- " << e.dest << " == " << e.weight << endl;
}
}
๐ **2. Primโs Algorithm (Greedy, O(Vยฒ) or O(E log V) with Priority Queue)**
Primโs Algorithm starts from any node and **grows** the MST by selecting the **minimum weight edge** that connects to an already visited node.
void Prim(vector>>& graph, int V) {
priority_queue, vector>, greater>> pq;
vector key(V, INT_MAX), parent(V, -1);
vector inMST(V, false);
pq.push({0, 0}); // {cost, node}
key[0] = 0;
while (!pq.empty()) {
int u = pq.top().second;
pq.pop();
inMST[u] = true;
for (auto &[v, weight] : graph[u]) {
if (!inMST[v] && weight < key[v]) {
key[v] = weight;
pq.push({key[v], v});
parent[v] = u;
}
}
}
for (int i = 1; i < V; i++) {
cout << parent[i] << " - " << i << " (weight: " << key[i] << ")\n";
}
}
โณ Time Complexity Analysis
Algorithm | Time Complexity |
---|---|
Kruskal's Algorithm | O(E log E) |
Primโs Algorithm (Priority Queue - Fibonacci Heap) | O(E log V) |
Primโs Algorithm (Adjacency Matrix) | O(Vยฒ) |
๐ Real-World Applications of MST
- ๐ก **Network Design** โ Laying down **minimum-cost communication cables.**
- ๐ **Road Systems** โ Designing **minimum-cost road networks.**
- ๐ **Computer Clustering** โ Connecting **servers with minimal latency.**
- ๐ฐ **Electric Grid Design** โ Optimizing **power transmission networks.**