3
Finding sum of distance from ith node to all other nodes takes O(n), so it4
will take O(n^2) if done naively to find distance for all.6
x---------------------y12
Above is a graph where x and y are subtrees with them as the root. They13
both are neighbors and are connected by an edge.33
As evident froma above, the tree structure looks different when we change34
the root of tree. So even if we find the sum of distance for node 0 as root,35
the subanswers are actually not correct for other nodes when they are the36
root of tree. The subanswers are only correct when node 0 is root, since that37
is how it was computed.39
We use something called re-rooting, this allows us to find a relation so40
that we can change the root of the tree and use the answer from its neighbor41
to compute answer for it. So if we compute the answer for node 0 as root, we42
can find the answers for its children, then those children can be used to43
compute for their neighbors and so on.46
distance[x] = sum(x) + sum(y) + count(y)48
distance[x] is the overall sum of distance with root as x49
sum(i) is the sum of distance of all the descendents for a subtree rooted at50
i count(i) is the no. of descendent nodes in the subtree rooted at i53
Consider a node z in subtree y, dist(x, z) = dist(y, z) + 154
So sum(y) already accounts for dist(y, z) and we just need to add 155
So if there are n_y nodes in the subtree, we need to add +1 that many times.57
distance[x] = sum(x) + sum(y) + count(y) -----------------158
distance[y] = sum(y) + sum(x) + count(x) -----------------261
distance[x] - distance[y] = count(y) - count(x) ----------362
distance[x] = distance[y] - count(x) + count(y)64
Above relation can be used to find the answer for a neighbor, when the65
answer for the other neighbor is known.67
In our case, we can compute the answer for node 0 as root in one traversal68
of post order. Then in another traversal with again root as 0, compute the69
answer for its children and from them to their children nodes and so on.71
distance[child] = distance[parent] - count(child) + (N - count(child))72
Since we also know the no. of nodes in subtree with child as root, the73
remaining nodes = (N - count(child))77
https://leetcode.com/problems/sum-of-distances-in-tree/solution/85
// subtree_distance[i] = Sum of distance to other nodes when the ith-node is87
vector<int> subtree_distance;88
// subtree_count[i] = no. of nodes in the subtree with ith-node as root89
vector<int> subtree_count;92
void postorder(int root, int parent, vector<vector<int>> &graph) {93
// Perform DFS for the child nodes94
for (auto child : graph[root]) {95
// Avoid iterating to the parent, it will create a loop otherwise96
if (child != parent) {97
postorder(child, root, graph);98
// Update the subtree count and sum of distance99
subtree_count[root] += subtree_count[child];100
// distance[X] = distance[X] + distance[Y] + n_Y101
subtree_distance[root] += subtree_distance[child] + subtree_count[child];106
void preorder(int root, int parent, vector<vector<int>> &graph) {107
for (auto child : graph[root]) {108
if (child != parent) {109
// distance[child] = distance[parent] - count[child] + count(parent)110
subtree_distance[child] =111
subtree_distance[root] - subtree_count[child] + (n - subtree_count[child]);112
preorder(child, root, graph);117
vector<int> reRootingSol(int n, vector<vector<int>> &edges) {118
// create an undirected graph119
vector<vector<int>> graph(n);120
for (auto edge : edges) {121
int src = edge[0], dst = edge[1];122
graph[src].emplace_back(dst);123
graph[dst].emplace_back(src);127
this->subtree_count.resize(n, 1);128
this->subtree_distance.resize(n, 0);130
// This computes the subtree sum and subtree node count when 0 is the root131
// of graph Imagine looking at the graph from node 0's POV132
postorder(0, -1, graph);133
// Since we have computed the sum distance from node's POV, we can use that134
// information to find the sum of distance from each node's POV i.e imagine135
// looking at the graph from POV of each node136
preorder(0, -1, graph);137
return this->subtree_distance;140
vector<int> sumOfDistancesInTree(int n, vector<vector<int>> &edges) {141
return reRootingSol(n, edges);