← Back to DSA Course | Chapter 13: Graphs | Lesson 9 of 10

Minimum Spanning Tree यानि Kruskal Algorithm

Kruskal का algorithm सभी houses को सबसे सस्ती possible pipes से connect करने जैसा है हमेशा सबसे सस्ती pipe चुनते हुए जो एक loop न बनाए।
Syntax
markup
edges.sort(key=lambda e: e[2])    # (u, v, weight)
for u, v, w in edges:
    if find(u) != find(v):
        union(u, v)
        mst.append((u, v, w))

What is MST

एक minimum spanning tree किसी weighted graph के हर vertex को सबसे छोटी possible total edge weight उपयोग करके connect करता है, बिना किसी cycle के — इसे हर building तक cable बिछाने का सबसे सस्ता तरीका सोचें, कोई redundant loops के बिना।

उदाहरण: What is MST

#include <iostream>
using namespace std;
int main() {
	int edges[][3] = {{0,1,4},{1,2,2},{0,2,5}};
	cout << "MST: connect all vertices, no cycles, minimum total weight";
	return 0;
}
public class Main {
	public static void main(String[] args) {
		int[][] edges = {{0,1,4},{1,2,2},{0,2,5}};
		System.out.println("MST: connect all vertices, no cycles, minimum total weight");
	}
}
edges = [(0,1,4),(1,2,2),(0,2,5)]
print("MST: connect all vertices, no cycles, minimum total weight")
#include <stdio.h>
int main() {
	int edges[3][3] = {{0,1,4},{1,2,2},{0,2,5}};
	printf("MST: connect all vertices, no cycles, minimum total weight");
	return 0;
}

Kruskal Idea

Kruskal का algorithm हर edge को सबसे सस्ते से सबसे महंगे तक sort करता है और उसी order में उनमें चलता है, एक edge को tree में सिर्फ तब जोड़ते हुए अगर यह पहले से चुनी edges के साथ कोई cycle न बनाए।

उदाहरण: Kruskal Idea

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
	vector<vector<int>> edges = {{0,1,4},{1,2,2},{0,2,5}};
	sort(edges.begin(), edges.end(), [](auto&a, auto&b){ return a[2] < b[2]; });
	cout << "Cheapest edge first: " << edges[0][0] << "-" << edges[0][1] << " (w=" << edges[0][2] << ")";
	return 0;
}
import java.util.*;
public class Main {
	public static void main(String[] args) {
		int[][] edges = {{0,1,4},{1,2,2},{0,2,5}};
		Arrays.sort(edges, (a,b) -> a[2]-b[2]);
		System.out.println("Cheapest edge first: " + edges[0][0] + "-" + edges[0][1] + " (w=" + edges[0][2] + ")");
	}
}
edges = [[0,1,4],[1,2,2],[0,2,5]]
edges.sort(key=lambda e: e[2])
print(f"Cheapest edge first: {edges[0][0]}-{edges[0][1]} (w={edges[0][2]})")
#include <stdio.h>
int main() {
	int edges[3][3] = {{0,1,4},{1,2,2},{0,2,5}};
	for (int i = 0; i < 3; i++)
		for (int j = i+1; j < 3; j++)
			if (edges[j][2] < edges[i][2]) { int t[3]; for(int k=0;k<3;k++){t[k]=edges[i][k];edges[i][k]=edges[j][k];edges[j][k]=t[k];} }
	printf("Cheapest edge first: %d-%d (w=%d)", edges[0][0], edges[0][1], edges[0][2]);
	return 0;
}

Disjoint Set

एक disjoint set (union-find) track करता है कौन सी vertices पहले से एक-दूसरे से connected हैं; एक edge जोड़ने से पहले, Kruskal जांचता है कि इसके दोनों endpoints पहले से उसी set में हैं या नहीं — अगर हैं, वह edge सिर्फ एक cycle बनाएगी और skip कर दी जाती है।

उदाहरण: Disjoint Set

#include <iostream>
using namespace std;
int parent[3] = {0,1,2};
int find(int x) { return parent[x]==x ? x : find(parent[x]); }
int main() {
	int u = 0, v = 1;
	if (find(u) != find(v)) { cout << "Different sets, add edge, union them"; parent[find(u)] = find(v); }
	else cout << "Same set already, edge would create a cycle -- skip";
	return 0;
}
public class Main {
	static int[] parent = {0,1,2};
	static int find(int x) { return parent[x]==x ? x : find(parent[x]); }
	public static void main(String[] args) {
		int u = 0, v = 1;
		if (find(u) != find(v)) { System.out.print("Different sets, add edge, union them"); parent[find(u)] = find(v); }
		else System.out.print("Same set already, edge would create a cycle -- skip");
	}
}
parent = [0, 1, 2]
def find(x):
    return x if parent[x] == x else find(parent[x])
u, v = 0, 1
if find(u) != find(v):
    print("Different sets, add edge, union them", end="")
    parent[find(u)] = find(v)
else:
    print("Same set already, edge would create a cycle -- skip", end="")
#include <stdio.h>
int parent[3] = {0,1,2};
int find(int x) { return parent[x]==x ? x : find(parent[x]); }
int main() {
	int u = 0, v = 1;
	if (find(u) != find(v)) { printf("Different sets, add edge, union them"); parent[find(u)] = find(v); }
	else printf("Same set already, edge would create a cycle -- skip");
	return 0;
}

Example

पांच cities और हर pair के बीच एक road बनाने की cost की कल्पना करें: Kruskal पहले सबसे सस्ता road चुनता है, फिर अगला सबसे सस्ता जो दो पहले से linked cities को फिर connect न करे, तब तक जारी रखते हुए जब तक सभी cities न जुड़ जाएं।

उदाहरण: Example

#include <iostream>
using namespace std;
int main() {
	cout << "5 cities: pick cheapest road, then next cheapest that doesn't reconnect two linked cities";
	return 0;
}
public class Main {
	public static void main(String[] args) {
		System.out.println("5 cities: pick cheapest road, then next cheapest that doesn't reconnect two linked cities");
	}
}
print("5 cities: pick cheapest road, then next cheapest that doesn't reconnect two linked cities")
#include <stdio.h>
int main() {
	printf("5 cities: pick cheapest road, then next cheapest that doesn't reconnect two linked cities");
	return 0;
}

Complexity

सभी E edges को sort करने में O(E log E) लगता है, जो running time को dominate करता है क्योंकि बाद आने वाले union-find operations path compression के साथ लगभग constant time हैं — इसलिए overall complexity essentially sort की cost है।

उदाहरण: Complexity

#include <iostream>
using namespace std;
int main() {
	cout << "Kruskal: O(E log E) dominated by sorting edges, union-find is nearly constant with path compression";
	return 0;
}
public class Main {
	public static void main(String[] args) {
		System.out.println("Kruskal: O(E log E) dominated by sorting edges, union-find is nearly constant with path compression");
	}
}
print("Kruskal: O(E log E) dominated by sorting edges, union-find is nearly constant with path compression")
#include <stdio.h>
int main() {
	printf("Kruskal: O(E log E) dominated by sorting edges, union-find is nearly constant with path compression");
	return 0;
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
आम गलतियां
  1. Union-find से यह जांचे बिना edges जोड़ना कि उनके endpoints पहले से connected हैं या नहीं, जो cycles बनाता है।
  2. पहले edges को weight से sort करना भूल जाना, इसलिए tree minimal नहीं है।
  3. V - 1 edges के बाद न रुकना, या यह notice न करना कि एक disconnected graph का कोई spanning tree नहीं है।

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.