Pattern #63
Prim's Algorithm
Grow an MST from one connected region using a min heap, cheapest frontier edges, visited-node cycle avoidance, parent reconstruction, and dense-graph variants.
Must Solve
15 core questions.
- 1.Min Cost to Connect All Pointsmedium
- 2.Connecting Cities With Minimum Costmedium
- 3.Minimum Spanning Tree Using Primmedium
- 4.Minimum Cost to Connect All Nodesmedium
- 5.Optimize Water Distribution — MST Relationmedium
- 6.Minimum Cost Network Connectionmedium
- 7.Minimum Cost to Connect Islandsmedium
- 8.Prim's Algorithm with Adjacency Listhard
- 9.Prim's Algorithm with Matrixhard
- 10.Minimum Spanning Foresthard
- 11.Dense Graph MSThard
- 12.Maximum Spanning Tree — Varianthard
- 13.MST with Pre-Connected Nodeshard
- 14.Minimum Cost Grid / Point Connectionhard
- 15.Compare Prim vs Kruskalhard
Also Important
- 16.Second Minimum Spanning Tree — Advancedmedium
- 17.Critical MST Edgesmedium
- 18.Dynamic MST — Advancedmedium
- 19.Euclidean / Manhattan MST Variantsmedium
- 20.Network Design Problemsmedium
How to Think
Minimum Spanning TreePrimMin HeapCandidate edges to unvisited nodesStart from any node with edge weight 0
↓
Pop cheapest candidate edge
↓
Already visited? Skip it
↓
Add node and edge cost
↓
Push its outgoing candidate edgesGo Quick Reference — Heap Prim
pq := MinHeap{{weight: 0, node: start, parent: -1}}
visited := make([]bool, n)
cost, used := 0, 0
for pq.Len() > 0 {
cur := heap.Pop(&pq).(Edge)
if visited[cur.node] { continue }
visited[cur.node] = true
cost += cur.weight
used++
parent[cur.node] = cur.parent
for _, edge := range graph[cur.node] {
if !visited[edge.to] { heap.Push(&pq, edge) }
}
}
if used != n { return -1 }
return costThe initial zero weight brings the starting node into the tree without charging for a fake edge.
Prim Variants & Comparisons
Prim vs Dijkstra
Prim stores cheapest incoming edge; Dijkstra stores cheapest full path from a source.
Prim vs Kruskal
Prim grows one frontier; Kruskal globally sorts edges and merges components.
Dense graph Prim
Scan a best-edge array in O(V²), avoiding an explicit heap and O(V²) edge list.
Parent array
When a node enters the tree, its chosen parent records the actual MST edge.
Disconnected graph
One run visits only one component; reject or restart to build a forest.
Start node
In a connected graph, the start may change the chosen MST but not the minimum total cost.
Tree starts → any node at cost 0
Heap → candidate frontier edges
Visited pop → skip before cost
New node → accept edge + push neighbors
Visited count V → MST completeComplexity
Adjacency list + heap: O(E log V) time, O(V + E) space
Adjacency matrix: O(V²) time, O(V) extra space
Complete point graph: O(V²) dense Prim can avoid O(V²) stored edgesCommon Interview Mistakes
• Confusing Prim with Dijkstra
• Adding cost for an already visited node
• Marking a node visited when pushed instead of when selected
• Not pushing the newly selected node’s outgoing edges
• Forgetting the connectivity check
• Using directed edges for an MST
• Thinking the start node changes minimum total cost
• Assuming MST paths are source shortest paths
Interview Rules
Grow one MST → Prim
Heap item → (edge weight, node, parent)
Start item → (0, start, -1)
Visited node → skip before adding cost
New node → add cost + push edges
Completion → visited count == V
Dense graph → O(V²) matrix Prim
Shortest paths → Dijkstra, not PrimProduction Thinking
Geographic networks → grow cable, fiber, or power connections from an existing region.
Dense point graphs → O(V²) Prim avoids materializing and sorting every pair edge.
Production warning → check visited before adding cost; duplicate heap candidates are normal.
Remember This
Prim → grow one MST
Heap key → incoming edge weight
Start → cost 0
Visited pop → skip
New node → add cost
Parent → chosen MST edge
Time → O(E log V)💡 Golden Rule: Always add the cheapest edge that crosses from the current tree to an unvisited node.