AlgoMaster Logo

Sum of Distances in Tree

Last Updated: March 28, 2026

hard
3 min read

Understanding the Problem

We have an unweighted tree with n nodes, and we need to compute, for every node, the total distance to all other nodes. If you think about it naively, you could run a BFS from each node to find distances to every other node. But with n up to 30,000, that O(n^2) approach is going to be tight.

The real question is: can we compute the answer for all nodes without starting from scratch each time? If we already know the answer for one node, can we figure out the answer for its neighbor cheaply? That idea of "rerooting" the tree, computing the answer at one root and then shifting it to adjacent nodes, is the core technique here.

Key Constraints:

  • 1 <= n <= 3 * 10^4 → With n up to 30,000, O(n^2) gives about 900 million operations. That is borderline and likely too slow for strict time limits. We need O(n) or O(n log n).
  • edges.length == n - 1 → Confirms this is a tree (connected, no cycles). Every pair of nodes has exactly one path between them.
  • The tree is unweighted, so distance equals the number of edges on the path.

Approach 1: BFS from Every Node

Intuition

The most direct way to solve this: for each node, run a BFS (or DFS) to compute the distance to every other node. Sum those distances. Repeat for all n nodes.

This is simple to implement and easy to reason about. For each node, BFS visits every other node exactly once, giving us the total distance in O(n). Doing this for all n nodes is O(n^2).

Algorithm

  1. Build an adjacency list from the edges.
  2. For each node i from 0 to n-1:
    • Run BFS starting from node i.
    • Sum up the distances to all other nodes.
    • Store the sum in answer[i].
  3. Return the answer array.

Example Walkthrough

1BFS from node 0: start at root, dist[0]=0
0dist=012345
1/4

Code

We run a full BFS from every single node, completely ignoring the work done by previous runs. The distance sums for neighboring nodes are closely related, so what if we computed the answer for one root, then figured out how it changes when we shift the root to a neighbor?

Approach 2: Rerooting DP (Optimal)

Intuition

Here is the key insight that makes this problem elegant. Suppose we already know answer[p], the sum of distances from some parent node p. Now consider one of p's children c. When we move the "center" from p to c, what happens to the distances?

Every node in c's subtree gets 1 unit closer (because we moved toward them). Every node outside c's subtree gets 1 unit farther (because we moved away from them). If count[c] is the number of nodes in c's subtree, then:

  • count[c] nodes each get 1 closer, so distance decreases by count[c]
  • n - count[c] nodes each get 1 farther, so distance increases by n - count[c]

That gives us: answer[c] = answer[p] + n - 2 * count[c]

Once we know the answer for the root, we can compute the answer for every other node in O(1) per node. The whole algorithm runs in O(n).

Algorithm

  1. Build an adjacency list from the edges.
  2. DFS 1 (Post-order): Root the tree at node 0. Compute count[i] (number of nodes in the subtree rooted at i) and answer[0] (sum of distances from node 0 to all other nodes).
    • For each node, count[node] = 1 + sum(count[child]) for all children.
    • For the root, answer[0] = sum of all depths (computed during the DFS).
  3. DFS 2 (Pre-order): Propagate the answer from parent to child using the rerooting formula.
    • For each child c of parent p: answer[c] = answer[p] + n - 2 * count[c].
  4. Return the answer array.

Example Walkthrough

1DFS 1: Start post-order from root 0
0root12345
1/8

Code