Browse curriculum

Min Cost to Connect All Points

Connect every point at the least total Manhattan distance with Prim's algorithm: a min-heap always attaches the cheapest new point to the tree.

Problem Understanding

Min Cost to Connect All Points: given points[i] = [x, y], connecting two points costs their Manhattan distance |x1 - x2| + |y1 - y2|. Return the minimum total cost so that every point is connected, meaning there is exactly one path between any two points.

Example: points = [[0,0],[2,2],[3,10],[5,2],[7,0]] returns 20.

The Intuition: Grow One Tree, Cheapest Edge First

Connecting all points with no cycles and the least total cost is a minimum spanning tree. Prim's algorithm grows it one point at a time:

  1. Start with point 0 alone in the tree.
  2. Of all edges from a tree point to a non-tree point, take the cheapest. That edge is always safe: any spanning tree must cross from "in" to "out" somewhere, and the cheapest crossing can never make it worse.
  3. Repeat until every point is in.

A min-heap holds the candidate edges, so the cheapest is one pop away. Each new point pushes its distance to every outside point; entries for points that joined in the meantime are stale and skipped. It is the same pop-cheapest-then-push loop as Network Delay Time's Dijkstra, except the key is the edge cost alone, not the distance from a source.

Interactive Walkthrough

Points are drawn at their coordinates. The tree grows in green; the heap of candidate edges is listed beside it, cheapest first. Try Stale entry to see an old, more expensive entry popped and skipped.

Dry Run Table

Input: points = [[0,0],[2,2],[3,10],[5,2],[7,0]]

Pop (cost, point) Action Total
(0, 0) start the tree at point 0 0
(4, 1) add 0 — 1 4
(3, 3) add 1 — 3 7
(4, 4) add 3 — 4 11
three pops points already in the tree: stale, skipped 11
(9, 2) add 1 — 2 20

Answer: 20, using 4 edges for 5 points.

The Solution Template

Lazy Prim with a heap. JavaScript and TypeScript include a small binary heap. C uses the O(n²) array version of Prim, which keeps the cheapest known cost for each outside point instead of a heap.

Min Cost to Connect All Points Code
1var minCostConnectPoints = function(points) {
2 const n = points.length, inTree = Array(n).fill(false);
3 const heap = [[0, 0]];
4 let total = 0, added = 0;
5 while (added < n) {
6 const [cost, u] = pop(heap);
7 if (inTree[u]) continue;
8 inTree[u] = true;
9 total += cost;
10 added++;
11 for (let v = 0; v < n; v++) {
12 if (!inTree[v]) {
13 const d = Math.abs(points[u][0] - points[v][0]) + Math.abs(points[u][1] - points[v][1]);
14 push(heap, [d, v]);
15 }
16 }
17 }
18 return total;
19};
20
21// Minimal binary min-heap on [cost, point] pairs.
22function push(heap, item) {
23 heap.push(item);
24 let i = heap.length - 1;
25 while (i > 0) {
26 const p = (i - 1) >> 1;
27 if (heap[p][0] <= heap[i][0]) break;
28 [heap[p], heap[i]] = [heap[i], heap[p]];
29 i = p;
30 }
31}
32
33function pop(heap) {
34 const top = heap[0], last = heap.pop();
35 if (heap.length) {
36 heap[0] = last;
37 let i = 0;
38 while (true) {
39 let m = i;
40 const l = 2 * i + 1, r = l + 1;
41 if (l < heap.length && heap[l][0] < heap[m][0]) m = l;
42 if (r < heap.length && heap[r][0] < heap[m][0]) m = r;
43 if (m === i) break;
44 [heap[m], heap[i]] = [heap[i], heap[m]];
45 i = m;
46 }
47 }
48 return top;
49}

Edge Cases & Common Mistakes

  • One point: nothing to connect; the answer is 0.
  • Forgetting the in-tree check: a stale entry would add the same point twice and overcount the cost.
  • Euclidean instead of Manhattan: the cost is |dx| + |dy|, no square root.
  • Building all n² edges for Kruskal: works, but sorts about n²/2 edges; Prim avoids the full list.
  • Ties: any cheapest edge is fine; different tie choices give different trees with the same total.

Summary

Treat the points as a complete graph with Manhattan weights and build a minimum spanning tree with Prim's algorithm: pop the cheapest attachment, skip it if stale, add the point and push its costs to every outside point. O(n² log n) time with a heap, or O(n²) with the array version.

More practice: DSA interview questions with answers · patterns cheat sheet

The approach, step by step

  1. Start the tree

    Push (0, 0): point 0 joins for free. Keep an in-tree flag for every point.

  2. Pop the cheapest attachment

    Pop (cost, u). If u is already in the tree, skip it. Otherwise add u and the cost to the total.

  3. Push the new options

    For every point v outside the tree, push (Manhattan distance from u to v, v). Stop when all n points are in the tree.

Frequently asked questions

Why is Min Cost to Connect All Points a minimum spanning tree problem?

Every pair of points can be joined at their Manhattan distance, so the points form a complete weighted graph. Connecting all of them as cheaply as possible, with no wasted edges, is exactly a minimum spanning tree: n - 1 edges with the smallest total cost.


Prim or Kruskal for this problem?

Both work. The graph is complete, with n(n - 1)/2 edges, so Prim's algorithm is the natural fit: it never builds the full edge list up front. The O(n²) array version of Prim, without a heap, is optimal for dense graphs. Kruskal must sort every edge, O(n² log n), and needs union-find.


What is a stale heap entry in Prim's algorithm?

A point can be pushed several times, once from each tree point that reaches it. After the cheapest one adds it to the tree, the others are still in the heap. When one is popped, its point is already in the tree, so it is skipped.

Applying for software engineering roles? Free, no sign-up:

AI resume checker — match your resume to the job description