🚀 Phases 1–5 are live — Days 1–17 cover the foundations and the algorithmic patterns. See the roadmap →

Prim’s Algorithm

Prim’s algorithm (1957) takes a different angle: instead of sorting all edges globally, it grows the MST one vertex at a time from an arbitrary starting node. At each step it asks: “what’s the cheapest edge connecting the current tree to a vertex not yet in the tree?”

This is also justified by the cut property: at every step, S = the set of vertices already in the tree and V − S = the rest. Prim’s always picks the minimum crossing edge — the cut property guarantees this is the right move.

The algorithm

Initialize

Mark all vertices as “not in tree.” Put the start vertex in the tree with cost 0. Push all edges of the start vertex into a min-heap (priority queue keyed by edge weight).

Greedy extension loop

While the tree has fewer than n vertices:

  1. Pop the cheapest edge (w, u, v) from the heap.
  2. If v is already in the tree — skip (this edge would create a cycle).
  3. Otherwise, add v to the tree. Record w as v’s “key” (its contribution to the MST cost). Push all edges of v into the heap.

Done

When n vertices are in the tree, the MST is complete.

Worked example

Same graph as before. Starting from vertex A.

StepHeap topActionTree
InitAdd A, push A’s edges: (4,A→B), (2,A→C)A
1(2, A→C)Add C, push C’s edges: (1,C→B), (8,C→E)A, C
2(1, C→B)Add B, push B’s edges: (5,B→D)A, C, B
3(4, A→B)B already in tree — skipA, C, B
4(5, B→D)Add D, push D’s edges: (2,D→E), (6,D→F)A, C, B, D
5(2, D→E)Add E, push E’s edges: (3,E→F)A, C, B, D, E
6(3, E→F)Add FA, C, B, D, E, F

MST edges: A-C(2), C-B(1), B-D(5), D-E(2), E-F(3). Total: 13. Same MST as Kruskal’s.

Prim's MST (starting from A) — same edges, total weight 13
42158263ABCDEF
6 nodes · 8 edges · weighted

Implementation — lazy Prim’s (heap of edges)

The “lazy” variant pushes all edges of a newly added vertex into the heap without removing stale entries. Stale entries (edges to already-added vertices) are detected and skipped when popped.

Eager Prim’s — fewer heap entries

The lazy version may put O(E) entries in the heap. The “eager” variant maintains, for each unvisited vertex v, only the current best edge connecting it to the tree. When a shorter edge is found, it decreases the key in the heap (a “decrease-key” operation).

With a Fibonacci heap, eager Prim’s runs in O(E + V log V). With a standard binary heap, decrease-key is O(log V) per update, giving O(E log V) — same asymptotic as the lazy version but with a smaller heap.

For competitive programming and interviews, lazy Prim’s is almost always sufficient. Implement eager only if explicitly asked for the Fibonacci-heap version.

Dense-graph Prim’s: O(V²) with an array

For dense graphs (E ≈ V²), using an adjacency matrix and scanning all vertices instead of a heap gives O(V²) — better than O(E log E) = O(V² log V).

def prim_dense(n, dist_matrix):
    # dist_matrix[i][j] = edge weight, float('inf') if no edge
    key = [float('inf')] * n
    in_tree = [False] * n
    key[0] = 0
    total = 0
 
    for _ in range(n):
        # Find the unvisited vertex with the smallest key
        u = min((i for i in range(n) if not in_tree[i]), key=lambda i: key[i])
        in_tree[u] = True
        total += key[u]
        for v in range(n):
            if not in_tree[v] and dist_matrix[u][v] < key[v]:
                key[v] = dist_matrix[u][v]
    return total

This O(V²) version is the right choice for:

  • Complete graphs (every pair of vertices connected)
  • Min Cost to Connect All Points (LC 1584), where the graph is implicitly complete

Kruskal’s vs Prim’s

PropertyKruskal’sPrim’s (lazy)
ApproachGlobal edge sort + union-findLocal greedy growth from one vertex
Time (sparse)O(E log E)O(E log V)
Time (dense)O(E log E) = O(V² log V)O(V²) with array
Data structureUnion-FindPriority queue
Handles disconnected graphsYes (spanning forest)No (stays in one component)
ImplementationOften shorterMore intuitive for some
Best forSparse graphs, edge-list inputDense graphs, adjacency matrix

In practice, for most interview problems (sparse graphs, edge list given): use Kruskal’s. For geometric problems where every pair of points is connected (like Min Cost to Connect All Points): use Prim’s dense variant with O(V²), which avoids explicitly creating all O(V²) edges.

Quick check

In lazy Prim's, what causes 'stale' entries in the heap, and how are they handled?
Why is dense Prim's O(V²) faster than Kruskal's on a complete graph?

Next: Advanced Patterns — Borůvka’s algorithm, minimum bottleneck spanning trees, second-best MST, and real-world MST applications.