Graph Algorithm
Prim's Algorithm
“The Greedy Architect”
History
This algorithm is a classic case of "scientific rediscovery." It was originally developed by Czech mathematician Vojtěch Jarník in 1930, then rediscovered by Robert Prim in 1957, and then *again* by Dijkstra in 1959.
It solves the "Minimum Spanning Tree" (MST) problem: how do you connect every city in a country with the least amount of road, without creating any loops?
How It Works
Prim's Algorithm grows a single tree from a starting seed. It feels very similar to Dijkstra's Algorithm, but with a different goal.
The Algorithm Step-by-Step
- Start: Pick an arbitrary node to be the "seed" of the tree.
- Inspect: Look at all edges connecting the *inside* of the tree to the *outside* world.
- Select: Pick the edge with the smallest weight.
- Grow: Add that edge and the new node to the tree.
- Repeat: Keep adding the cheapest connection until all nodes are included.
The Difference from Dijkstra
Dijkstra picks the next node based on the *total distance from the start*. Prim picks the next node based on the *shortest single jump* from the current tree.
We process every edge ($E$) and push/pop from a Priority Queue ($log V$). With a Fibonacci Heap, you can optimize this further.
We need to store the graph and the priority queue.
The core data structure powering Prim's Algorithm.
How this algorithm appears during visualization.
Code Walkthrough
Real implementations in multiple programming languages. Select a language to view idiomatic code.
1import heapq2from collections import defaultdict34def prim(n: int, edges: list[tuple[int, int, int]]) -> list[tuple[int, int, int]]:5 """Find Minimum Spanning Tree using Prim's algorithm.67 Args:8 n: Number of vertices (0 to n-1)9 edges: List of (u, v, weight) tuples1011 Returns:12 List of edges in the MST as (u, v, weight) tuples13 """14 # Build adjacency list: node -> [(neighbor, weight), ...]15 graph: dict[int, list[tuple[int, int]]] = defaultdict(list)16 for u, v, w in edges:17 graph[u].append((v, w))18 graph[v].append((u, w))1920 mst: list[tuple[int, int, int]] = []21 visited: set[int] = set()2223 # Min-heap: (weight, from_node, to_node)24 # Start from node 025 heap: list[tuple[int, int, int]] = [(0, -1, 0)]2627 while heap and len(visited) < n:28 weight, from_node, to_node = heapq.heappop(heap)2930 if to_node in visited:31 continue3233 visited.add(to_node)3435 # Add edge to MST (skip the initial dummy edge)36 if from_node != -1:37 mst.append((from_node, to_node, weight))3839 # Explore neighbors40 for neighbor, edge_weight in graph[to_node]:41 if neighbor not in visited:42 heapq.heappush(heap, (edge_weight, to_node, neighbor))4344 return mstReal World Use Cases
- 1Network Cabling (connecting servers with minimal wire)
- 2Road Network Design
- 3Cluster Analysis in Machine Learning
- 4Maze Generation (randomized Prim's)
- 5Circuit Board routing
Key Insights
- It is a Greedy Algorithm (local optimum = global optimum).
- It always maintains a single, connected component.
- It works best on Dense Graphs (lots of edges).
- It fails on graphs with disconnected parts (it can only span one island).
When to Use
Use Prim's when the graph is dense (lots of edges per node) or when you need to grow a network outward from a specific central point.
When NOT to Use
Avoid Prim's if the graph is sparse (Kruskal's is usually cleaner) or if you need to find the MST of a disconnected graph (a Minimum Spanning Forest).
Interview Tip
Remember that Prim's is essentially Dijkstra's algorithm, just with a slightly different sorting key in the Priority Queue. If you know one, you know the other.