We have an unweighted tree with n nodes, and we need to compute, for every node, the total distance to all other nodes. The direct solution runs a BFS from each node to find distances to every other node, but with n up to 30,000 that is O(n^2), around 900 million operations.
The better idea is to compute the answer for all nodes without starting from scratch each time. If we already know the answer for one node, we can derive the answer for its neighbor in O(1). That technique, computing the answer at one root and then shifting it to adjacent nodes, is called rerooting, and it brings the total down to O(n).
1 <= n <= 3 * 10^4 → O(n^2) is about 900 million operations, too slow for strict time limits. We need an O(n) solution.edges.length == n - 1 → This is a tree: connected, no cycles. Every pair of nodes has exactly one path between them, so distance is well defined.int is safe in every language here.For each node, run a BFS to compute the distance to every other node, then sum those distances. Repeat for all n nodes.
For a single source, BFS visits every other node exactly once and assigns each its distance from the source, so one BFS gives that node's total in O(n). Running it from all n sources is O(n^2). This is a useful baseline because it directly encodes the definition of the answer, and it establishes the correct results we will reproduce faster in the next approach.
i from 0 to n-1:i.answer[i].This repeats a full BFS from every node and discards the work each run does. The distance sums for neighboring nodes are closely related, and the next approach exploits that relationship: compute the answer once for a chosen root, then derive each neighbor's answer from it in constant time.
Root the tree at node 0 and suppose we know answer[p] for a node p. Take one of p's children c. Moving the reference point from p to c shifts every distance by exactly one edge, because p and c are adjacent. Split the nodes by which side of the edge p-c they lie on:
c's subtree are reached through c, so moving to c brings each of them 1 closer.p, so moving to c puts each of them 1 farther.If count[c] is the number of nodes in c's subtree, then count[c] distances drop by 1 and n - count[c] distances rise by 1:
answer[c] = answer[p] - count[c] + (n - count[c]) = answer[p] + n - 2 * count[c]
This needs two pieces of information: the answer for the root and the subtree size of every node. A first DFS computes both. A second DFS walks down from the root applying the formula, giving each node's answer in O(1). The whole algorithm runs in O(n).
The formula uses count[c], the subtree size measured when the tree was rooted at node 0 in DFS 1. DFS 2 never recomputes it. This is safe because count[c] counts the nodes on c's side of the edge p-c, and removing that edge always splits the tree into the same two components no matter which endpoint we call the root. So count[c] is exactly the number of nodes 1 closer when we move from p to c, and n - count[c] is the number 1 farther. Both quantities depend only on the edge, not on the rooting, so the value carried over from DFS 1 remains correct at every step.
parent[node] and the order nodes are popped. Because a child is always popped after its parent, the reverse of this order is a valid bottom-up (post-order) processing sequence.count[node] = 1 + sum(count[child]) over its children, and accumulate answer[0] as answer[node] += answer[child] + count[child]. After this pass, answer[0] holds the sum of distances from the root, and count[i] holds every subtree size.c with parent p, apply answer[c] = answer[p] + n - 2 * count[c]. The parent is always processed before the child, so answer[p] is final when c is computed.The two passes use an explicit stack and array iteration rather than recursion. With n up to 30,000, a path-shaped tree has a recursion depth of 30,000, which overflows the default call stack in several languages. The iterative form keeps the depth bounded by the heap-allocated stack and avoids that failure.