A spanning tree of an undirected graph is a subgraph that includes all vertices but only enough edges to keep the graph connected (exactly |V| - 1 edges). When edges have weights, the Minimum Spanning Tree (MST) is the spanning tree with the smallest total edge weight.
V - 1 edges for V vertices.Prim's algorithm grows the MST one vertex at a time. It starts from an arbitrary vertex and repeatedly adds the cheapest edge that connects a visited vertex to an unvisited one.
def prim(graph, start):
n = len(graph)
visited = [False] * n
min_edge = [float('inf')] * n
min_edge[start] = 0
total_weight = 0
for _ in range(n):
u = -1
# Pick the unvisited vertex with smallest edge
for v in range(n):
if not visited[v] and (u == -1 or min_edge[v] < min_edge[u]):
u = v
visited[u] = True
total_weight += min_edge[u]
# Update edges to neighbors
for v, w in enumerate(graph[u]):
if w and not visited[v] and w < min_edge[v]:
min_edge[v] = w
return total_weight
Time complexity: O(V²) with an adjacency matrix, or O(E log V) with a binary heap.
Kruskal's algorithm sorts all edges by weight, then adds them one by one — skipping any edge that would create a cycle. It uses a Disjoint Set Union (DSU) or Union-Find data structure to detect cycles efficiently.
find(u) != find(v), add the edge to the MST and union the sets of u and v.V - 1 edges.class DSU:
def __init__(self, n):
self.parent = list(range(n))
self.rank = [0] * n
def find(self, x):
if self.parent[x] != x:
self.parent[x] = self.find(self.parent[x])
return self.parent[x]
def union(self, x, y):
rx, ry = self.find(x), self.find(y)
if rx == ry:
return False
if self.rank[rx] < self.rank[ry]:
self.parent[rx] = ry
elif self.rank[rx] > self.rank[ry]:
self.parent[ry] = rx
else:
self.parent[ry] = rx
self.rank[rx] += 1
return True
def kruskal(vertices, edges):
edges.sort(key=lambda e: e[2])
dsu = DSU(vertices)
mst_weight = 0
count = 0
for u, v, w in edges:
if dsu.union(u, v):
mst_weight += w
count += 1
if count == vertices - 1:
break
return mst_weight
Time complexity: O(E log E) due to sorting, or O(E log V) with efficient DSU operations.
| Feature | Prim's Algorithm | Kruskal's Algorithm |
|---|---|---|
| Approach | Vertex-based (grows like BFS) | Edge-based (processes sorted edges) |
| Data Structure | Priority queue / heap | Union-Find (DSU) |
| Best for | Dense graphs (many edges) | Sparse graphs (few edges) |
| Time Complexity | O(E log V) with heap | O(E log E) — dominated by sorting |
| Graph Requirement | Connected graph | Connected or disconnected (finds forest) |
Implement both Prim's and Kruskal's algorithms on the following graph (vertices 0—4):
edges = [
(0, 1, 10), (0, 2, 6), (0, 3, 5),
(1, 3, 15), (2, 3, 4), (3, 4, 8)
]
Verify that both algorithms produce the same MST weight. Then modify your code to also return the list of edges in the MST.