A Bit of History
Prim's algorithm is a striking example of an idea being discovered, forgotten, and rediscovered. Czech mathematician Vojtěch Jarník published this exact "grow one tree outward" strategy in 1930 — a full 27 years before Robert Prim, an American mathematician at Bell Labs, independently rediscovered and popularized it in a 1957 paper. Because Jarník's paper was written in Czech and published in a regional journal, it went largely unnoticed outside Central Europe for decades — a genuine case of an important algorithm being "invented" three times: Jarník in 1930, Prim in 1957, and Edsger Dijkstra independently again in 1959 (in the very same short paper that introduced his shortest-path algorithm). Some textbooks now credit it as the "Jarník-Prim algorithm" in recognition of the earlier discovery.
Working Principle
Where Kruskal's algorithm works globally (sort every edge in the whole graph up front), Prim's algorithm works locally: start with a single arbitrary vertex as a one-vertex "tree," and repeatedly add the cheapest edge connecting the current tree to any vertex outside it, growing the tree by exactly one vertex each step. After \(n-1\) additions, every vertex is included and the MST is complete.
Analogy: An Expanding Territory, Always Annexing the Cheapest Neighbor
Picture a small kingdom (the growing tree) deciding which neighboring village to annex next. At every step, it looks only at villages directly bordering its current territory and annexes whichever one is cheapest to connect — never looking at villages far away that aren't yet reachable from the current border. This is exactly why Prim's algorithm needs a priority queue keyed on vertices (specifically, the cheapest known edge connecting each outside vertex to the tree) rather than a global sort of every edge in the graph.
Worked Example
The same graph as the Kruskal's deep dive: \(A\text{-}C\) (1), \(B\text{-}C\) (1), \(B\text{-}D\) (1), \(A\text{-}B\) (4), \(C\text{-}D\) (5). Start from \(A\).
| Step | Tree so far | Frontier edges considered | Cheapest added |
|---|---|---|---|
| 0 | {A} | A-C (1), A-B (4) | A-C (1) |
| 1 | {A,C} | A-B (4), C-B (1), C-D (5) | C-B (1) |
| 2 | {A,C,B} | A-B (skip, both endpoints in tree), B-D (1), C-D (5) | B-D (1) |
| 3 | {A,C,B,D} | — all vertices included, stop | — |
Same total weight (3) and, in this case, exactly the same edge set as Kruskal's algorithm found — the MST of a graph with distinct edge weights is always unique (an exercise from the Kruskal deep dive), so any correct algorithm must find it.
Correctness via the Cut Property
Prim's algorithm is, if anything, an even more direct application of the cut property (introduced in the Kruskal deep dive) than Kruskal's algorithm itself: at every step, the partition is literally "tree so far" versus "everything else," and the algorithm always adds the minimum-weight edge crossing exactly that cut — which the cut property guarantees is safe to add to some MST.
Complexity Analysis
With a binary-heap priority queue keyed by "cheapest known connecting edge weight" per outside vertex: \(V\) extractions at \(O(\log V)\) each, and up to \(E\) decrease-key operations at \(O(\log V)\) each:
$$\text{Time: } O((V+E)\log V) \qquad \text{Space: } O(V)$$
On a dense graph, a simpler \(O(V^2)\) array-based implementation (linear scan for the minimum each step, no heap at all) is often faster in practice — the same lesson from Dijkstra's algorithm applies here, since the underlying strategy is nearly identical.
Implementation
Prim vs. Kruskal
| Aspect | Prim's | Kruskal's |
|---|---|---|
| Strategy | grows one tree from a seed vertex | sorts all edges, adds globally cheapest safe edge |
| Best for | dense graphs; adjacency-matrix input | sparse graphs; edge-list input |
| Needs upfront | a starting vertex only | the entire edge list, sorted |
| Streaming-friendly? | yes — grows incrementally | no — needs global edge knowledge first |
Real-World Applications
Incremental Network Rollout
When a telecom or utility company expands a network incrementally — starting from an existing hub and deciding, year by year, which new site to connect next at minimum cost — Prim's "grow outward" structure matches the real-world constraint far better than Kruskal's "know every candidate edge up front" approach. The same incremental-growth pattern appears in real-time cluster/mesh network formation, where devices discover each other and join a minimum-cost spanning topology as they come online.
Exercises
- Run Prim's algorithm by hand starting from vertex \(D\) instead of \(A\) on the worked example's graph, and confirm the total MST weight is still 3.
- Explain why Prim's algorithm never needs to check for cycles explicitly (unlike Kruskal's Union-Find check) — what property of "grow one connected tree" makes a cycle structurally impossible to introduce?
- Implement the \(O(V^2)\) array-based version of Prim's algorithm (no heap) and compare its running time against the heap-based version on a very dense randomly generated graph.
- Challenge: Prove that Prim's algorithm and Kruskal's algorithm always produce the same total MST weight (though possibly different edge sets, if weights are not all distinct) by showing both correctly implement the same cut-property-driven greedy strategy.
Limitations
Adjacency Matrix Overhead on Sparse Graphs
Prim's algorithm needs fast "what are this vertex's neighbors" access, which favors an adjacency list or matrix — on a very sparse graph represented awkwardly (e.g., only as a raw edge list), Kruskal's algorithm can be simpler to apply directly. And like Kruskal's, Prim's algorithm computes an MST that is unaffected by negative weights (unlike shortest-path algorithms) — but it says nothing about shortest paths between vertices; an MST edge is not necessarily on the shortest path between its endpoints once other routes exist.