Open In App

Sum of distance from each node

Last Updated : 11 Dec, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a connected tree of N nodes, numbered from 1 to N. Since it is a tree, there is exactly one simple path between any two nodes. For every node in the tree, your task is to compute the sum of its distances to all other nodes.

Examples:

Input: N = 5, edges[][] = [[1, 2], [1, 3], [3, 4], [3, 5]]
Output: [6, 9, 5, 8, 8]
Explanation: From one node to other nodes:
Start at node 1-> sum of distances = 6
Start at node 2 -> sum of distances = 9
Start at node 3 -> sum of distances = 5
Start at node 4 -> sum of distances = 8
Start at node 5 -> sum of distances = 8
Therefore, the answer is [6, 9, 5, 8, 8].

Input: N = 2, edges[][] = [[1, 2]]
Output: [1, 1]
Explanation: From one node to other nodes:
Start at node 1 -> one edge to node 2 -> sum = 1
Start at node 2 -> one edge to node 1 -> sum = 1
Therefore, the answer is [1, 1].

[Naive Approach] Calculating Distances for Every Node Separately - O(N^2) Time and O(N) Space

The simplest approach is to consider each node as a starting point and compute the distance from that node to all other nodes using BFS. We repeat this for all nodes, and the sum of distances for each becomes our answer.

C++
#include <iostream>
#include <vector>
#include <queue>
using namespace std;

vector<int> sumOfDistances(int N, vector<vector<int>> &edges) {
    
    // Build adjacency list
    vector<vector<int>> adj(N + 1);
    
    for(auto &e : edges) {
        
        // Add both directions since graph is undirected
        adj[e[0]].push_back(e[1]);
        adj[e[1]].push_back(e[0]);
    }

    vector<int> ans(N + 1);

    // For each node, run BFS and calculate sum of distances
    for(int start = 1; start <= N; start++) {
        
        vector<int> dist(N + 1, -1);
        queue<int> q;

        // Start BFS from the current node
        dist[start] = 0;
        q.push(start);

        while(!q.empty()) {
            
            int node = q.front();
            q.pop();

            // Explore all adjacent nodes
            for(int nei : adj[node]) {
                
                // Visit unvisited neighbors
                if(dist[nei] == -1) {
                    
                    dist[nei] = dist[node] + 1;
                    q.push(nei);
                }
            }
        }

        // Sum all distances for this starting node
        int total = 0;
        
        for(int i = 1; i <= N; i++) {
            total += dist[i];
        }
        
        ans[start] = total;
    }

    return ans;
}

int main() {
    
    int N = 5;
    vector<vector<int>> edges = {{1, 2}, {1, 3}, {3, 4}, {3, 5}};

    // Compute result
    vector<int> result = sumOfDistances(N, edges);

    // Print output
    for(int i = 1; i <= N; i++) {
        cout << result[i] << " ";
    }

    return 0;
}
Java
import java.util.*;

public class GFG {

    static List<Integer> sumOfDistances(int N, List<List<Integer>> edges) {
        
        // Build adjacency list
        List<List<Integer>> adj = new ArrayList<>();
        for(int i = 0; i <= N; i++) adj.add(new ArrayList<>());
        
        for(List<Integer> e : edges) {
            
            // Add both directions since graph is undirected
            adj.get(e.get(0)).add(e.get(1));
            adj.get(e.get(1)).add(e.get(0));
        }

        List<Integer> ans = new ArrayList<>(Collections.nCopies(N + 1, 0));

        // For each node, run BFS and calculate sum of distances
        for(int start = 1; start <= N; start++) {
            
            int[] dist = new int[N + 1];
            Arrays.fill(dist, -1);
            Queue<Integer> q = new LinkedList<>();

            // Start BFS from the current node
            dist[start] = 0;
            q.add(start);

            while(!q.isEmpty()) {
                
                int node = q.poll();

                // Explore all adjacent nodes
                for(int nei : adj.get(node)) {
                    
                    // Visit unvisited neighbors
                    if(dist[nei] == -1) {
                        
                        dist[nei] = dist[node] + 1;
                        q.add(nei);
                    }
                }
            }

            // Sum all distances for this starting node
            int total = 0;
            
            for(int i = 1; i <= N; i++) {
                total += dist[i];
            }
            
            ans.set(start, total);
        }

        return ans;
    }

    public static void main(String[] args) {
        
        
        int N = 5;
        
        List<List<Integer>> edges = Arrays.asList(
            Arrays.asList(1,2), Arrays.asList(1,3),
            Arrays.asList(3,4), Arrays.asList(3,5)
        );

        // Compute result
        List<Integer> result = sumOfDistances(N, edges);

        // Print output
        for(int i = 1; i <= N; i++) {
            System.out.print(result.get(i) + " ");
        }
    }
}
Python
from collections import deque

def sumOfDistances(N, edges):
    
    # Build adjacency list
    adj = [[] for _ in range(N + 1)]
    
    for e in edges:
        
        # Add both directions since graph is undirected
        adj[e[0]].append(e[1])
        adj[e[1]].append(e[0])

    ans = [0] * (N + 1)

    # For each node, run BFS and calculate sum of distances
    for start in range(1, N + 1):
        
        dist = [-1] * (N + 1)
        q = deque()

        # Start BFS from the current node
        dist[start] = 0
        q.append(start)

        while q:
            
            node = q.popleft()

            # Explore all adjacent nodes
            for nei in adj[node]:
                
                # Visit unvisited neighbors
                if dist[nei] == -1:
                    
                    dist[nei] = dist[node] + 1
                    q.append(nei)

        # Sum all distances for this starting node
        total = 0
        
        for i in range(1, N + 1):
            total += dist[i]
        
        ans[start] = total

    return ans


if __name__ == "__main__":
    
    
    N = 5
    edges = [[1, 2], [1, 3], [3, 4], [3, 5]]

    # Compute result
    result = sumOfDistances(N, edges)

    # Print output
    for i in range(1, N + 1):
        print(result[i], end=" ")
C#
using System;
using System.Collections.Generic;

class GFG
{
    static List<int> sumOfDistances(int N, List<List<int>> edges) {
        
        // Build adjacency list
        List<List<int>> adj = new List<List<int>>();
        
        for(int i = 0; i <= N; i++) adj.Add(new List<int>());
        
        foreach(var e in edges) {
            
            // Add both directions since graph is undirected
            adj[e[0]].Add(e[1]);
            adj[e[1]].Add(e[0]);
        }

        List<int> ans = new List<int>(new int[N + 1]);

        // For each node, run BFS and calculate sum of distances
        for(int start = 1; start <= N; start++) {
            
            int[] dist = new int[N + 1];
            
            Array.Fill(dist, -1);
            Queue<int> q = new Queue<int>();

            // Start BFS from the current node
            dist[start] = 0;
            q.Enqueue(start);

            while(q.Count > 0) {
                
                int node = q.Dequeue();

                // Explore all adjacent nodes
                foreach(int nei in adj[node]) {
                    
                    // Visit unvisited neighbors
                    if(dist[nei] == -1) {
                        
                        dist[nei] = dist[node] + 1;
                        q.Enqueue(nei);
                    }
                }
            }

            // Sum all distances for this starting node
            int total = 0;
            
            for(int i = 1; i <= N; i++) {
                total += dist[i];
            }
            
            ans[start] = total;
        }

        return ans;
    }

    static void Main() {
        
        
        int N = 5;
        
        var edges = new List<List<int>> {
            new List<int>{1, 2}, new List<int>{1, 3},
            new List<int>{3, 4}, new List<int>{3, 5}
        };

        // Compute result
        var result = sumOfDistances(N, edges);

        // Print output
        for(int i = 1; i <= N; i++) {
            Console.Write(result[i] + " ");
        }
    }
}
JavaScript
function sumOfDistances(N, edges) {
    
    // Build adjacency list
    const adj = Array.from({ length: N + 1 }, () => []);
    
    edges.forEach(e => {
        
        // Add both directions since graph is undirected
        adj[e[0]].push(e[1]);
        adj[e[1]].push(e[0]);
    });

    const ans = new Array(N + 1).fill(0);

    // For each node, run BFS and calculate sum of distances
    for(let start = 1; start <= N; start++) {
        
        const dist = new Array(N + 1).fill(-1);
        const q = [];

        // Start BFS from the current node
        dist[start] = 0;
        q.push(start);

        while(q.length > 0) {
            
            const node = q.shift();

            // Explore all adjacent nodes
            for(const nei of adj[node]) {
                
                // Visit unvisited neighbors
                if(dist[nei] === -1) {
                    
                    dist[nei] = dist[node] + 1;
                    q.push(nei);
                }
            }
        }

        // Sum all distances for this starting node
        let total = 0;
        
        for(let i = 1; i <= N; i++) {
            total += dist[i];
        }
        
        ans[start] = total;
    }

    return ans;
}

// Driver Code
let N = 5;
let edges = [[1, 2], [1, 3], [3, 4], [3, 5]];

// Compute result
let result = sumOfDistances(N, edges);

// Print output
for(let i = 1; i <= N; i++) {
    process.stdout.write(result[i] + " ");
}

Output
6 9 5 8 8 

[Expected Approach] Using two DFS passes - O(N) Time and O(N) Space

The expected approach uses two DFS traversals to compute all distance sums efficiently in O(N) time. In the first DFS, we root the tree at node 1 and compute for each node: subSize[u] (how many nodes are in its subtree) and down[u] (the sum of distances from u to nodes in its subtree). This gives us the answer for the root. In the second DFS, we reroot the tree: when moving the root from a parent u to a child v, nodes in v’s subtree become 1 step closer and all other nodes become 1 step farther.

This leads to the formula ans[v] = ans[u]-subSize[v]+(N-subSize[v]), letting us compute each node’s distance sum in constant time while traversing. Thus, all answers are obtained in linear time without repeating BFS for every node.

C++
#include <iostream>
#include <vector>
using namespace std;

// First DFS: compute subSize and down values (post-order)
void dfs1(int u, int p, vector<vector<int>> &adj,
          vector<int> &subSize, vector<long long> &down) {
    
    // Initialize subtree size and down sum for node u
    subSize[u] = 1;
    down[u] = 0;

    // Visit children
    for (int v : adj[u]) {
        if (v == p) continue;

        dfs1(v, u, adj, subSize, down);

        // Add child's subtree size
        subSize[u] += subSize[v];

        // All nodes in child's subtree are one edge farther from u than from v
        down[u] += down[v] + subSize[v];
    }
}

// Second DFS: reroot and compute ans for all nodes (pre-order)
void dfs2(int u, int p, int N, vector<vector<int>> &adj,
          vector<int> &subSize, vector<long long> &ans) {
    
    // Visit children and reroot to compute their answers
    for (int v : adj[u]) {
        if (v == p) continue;

        // Move root from u to v:
        // Nodes in v's subtree get 1 closer (subtract subSize[v])
        // All other nodes get 1 farther (add N - subSize[v])
        ans[v] = ans[u] - subSize[v] + (N - subSize[v]);

        dfs2(v, u, N, adj, subSize, ans);
    }
}

// Wrapper function that computes all distances
vector<long long> computeDistances(int N, vector<vector<int>> &edges) {

    // Build adjacency list
    vector<vector<int>> adj(N + 1);
    for (auto &e : edges) {
        adj[e[0]].push_back(e[1]);
        adj[e[1]].push_back(e[0]);
    }

    vector<int> subSize(N + 1, 0);
    vector<long long> down(N + 1, 0);
    vector<long long> ans(N + 1, 0);

    // First DFS: compute subtree info
    dfs1(1, 0, adj, subSize, down);

    // Set root answer
    ans[1] = down[1];

    // Second DFS: reroot and compute answers for all nodes
    dfs2(1, 0, N, adj, subSize, ans);

    return ans;
}

int main() {
    
    
    int N = 5;
    vector<vector<int>> edges = {{1, 2}, {1, 3}, {3, 4}, {3, 5}};

    // Function call
    vector<long long> result = computeDistances(N, edges);

    // Print output
    for (int i = 1; i <= N; i++) {
        cout << result[i] << " ";
    }

    return 0;
}
Java
import java.util.*;

public class GFG {

    // First DFS: compute subSize and down values (post-order)
    static void dfs1(int u, int p, List<List<Integer>> adj, int[] subSize, long[] down) {
        
        // Initialize subtree size and down sum for node u
        subSize[u] = 1;
        down[u] = 0;

        // Visit children
        for (int v : adj.get(u)) {
            if (v == p) continue;

            dfs1(v, u, adj, subSize, down);

            // Add child's subtree size
            subSize[u] += subSize[v];

            // All nodes in child's subtree are one edge farther from u than from v
            down[u] += down[v] + subSize[v];
        }
    }

    // Second DFS: reroot and compute ans for all nodes (pre-order)
    static void dfs2(int u, int p, int N, List<List<Integer>> adj, int[] subSize, long[] ans) {
        
        // Visit children and reroot to compute their answers
        for (int v : adj.get(u)) {
            if (v == p) continue;

            // Move root from u to v:
            // Nodes in v's subtree get 1 closer (subtract subSize[v])
            // All other nodes get 1 farther (add N - subSize[v])
            ans[v] = ans[u] - subSize[v] + (N - subSize[v]);

            dfs2(v, u, N, adj, subSize, ans);
        }
    }

    // Wrapper function that computes all distances
    static long[] computeDistances(int N, List<int[]> edges) {

        // Build adjacency list
        List<List<Integer>> adj = new ArrayList<>();
        for (int i = 0; i <= N; i++) adj.add(new ArrayList<>());
        for (int[] e : edges) {
            adj.get(e[0]).add(e[1]);
            adj.get(e[1]).add(e[0]);
        }

        int[] subSize = new int[N + 1];
        long[] down = new long[N + 1];
        long[] ans = new long[N + 1];

        // First DFS: compute subtree info
        dfs1(1, 0, adj, subSize, down);

        // Set root answer
        ans[1] = down[1];

        // Second DFS: reroot and compute answers for all nodes
        dfs2(1, 0, N, adj, subSize, ans);

        return ans;
    }

    public static void main(String[] args) {
        
        
        int N = 5;
        List<int[]> edges = Arrays.asList(
            new int[]{1, 2}, new int[]{1, 3},
            new int[]{3, 4}, new int[]{3, 5}
        );

        // Function call
        long[] result = computeDistances(N, edges);

        // Print output
        for (int i = 1; i <= N; i++) {
            System.out.print(result[i] + " ");
        }
    }
}
Python
from typing import List

# First DFS: compute subSize and down values (post-order)
def dfs1(u: int, p: int, adj: List[List[int]], subSize: List[int], down: List[int]):
    
    # Initialize subtree size and down sum for node u
    subSize[u] = 1
    down[u] = 0

    # Visit children
    for v in adj[u]:
        if v == p:
            continue

        dfs1(v, u, adj, subSize, down)

        # Add child's subtree size
        subSize[u] += subSize[v]

        # All nodes in child's subtree are one edge farther from u than from v
        down[u] += down[v] + subSize[v]

# Second DFS: reroot and compute ans for all nodes (pre-order)
def dfs2(u: int, p: int, N: int, adj: List[List[int]], subSize: List[int], ans: List[int]):
    
    # Visit children and reroot to compute their answers
    for v in adj[u]:
        if v == p:
            continue

        # Move root from u to v:
        # Nodes in v's subtree get 1 closer (subtract subSize[v])
        # All other nodes get 1 farther (add N - subSize[v])
        ans[v] = ans[u] - subSize[v] + (N - subSize[v])

        dfs2(v, u, N, adj, subSize, ans)

# Wrapper function that computes all distances
def compute_distances(N: int, edges: List[List[int]]):
    
    # Build adjacency list
    adj = [[] for _ in range(N + 1)]
    for e in edges:
        adj[e[0]].append(e[1])
        adj[e[1]].append(e[0])

    subSize = [0] * (N + 1)
    down = [0] * (N + 1)
    ans = [0] * (N + 1)

    # First DFS: compute subtree info
    dfs1(1, 0, adj, subSize, down)

    # Set root answer
    ans[1] = down[1]

    # Second DFS: reroot and compute answers for all nodes
    dfs2(1, 0, N, adj, subSize, ans)

    return ans


if __name__ == "__main__":
    
    
    N = 5
    edges = [[1, 2], [1, 3], [3, 4], [3, 5]]

    # Function call
    result = compute_distances(N, edges)

    # Print output
    for i in range(1, N + 1):
        print(result[i], end=" ")
C#
using System;
using System.Collections.Generic;

class GFG
{
    // First DFS: compute subSize and down values (post-order)
    static void Dfs1(int u, int p, List<List<int>> adj, int[] subSize, long[] down) {
        
        // Initialize subtree size and down sum for node u
        subSize[u] = 1;
        down[u] = 0;

        // Visit children
        foreach (int v in adj[u]) {
            if (v == p) continue;

            Dfs1(v, u, adj, subSize, down);

            // Add child's subtree size
            subSize[u] += subSize[v];

            // All nodes in child's subtree are one edge farther from u than from v
            down[u] += down[v] + subSize[v];
        }
    }

    // Second DFS: reroot and compute ans for all nodes (pre-order)
    static void Dfs2(int u, int p, int N, List<List<int>> adj, int[] subSize, long[] ans) {
        
        // Visit children and reroot to compute their answers
        foreach (int v in adj[u]) {
            if (v == p) continue;

            // Move root from u to v:
            // Nodes in v's subtree get 1 closer (subtract subSize[v])
            // All other nodes get 1 farther (add N - subSize[v])
            ans[v] = ans[u] - subSize[v] + (N - subSize[v]);

            Dfs2(v, u, N, adj, subSize, ans);
        }
    }

    // Wrapper function that computes all distances
    static long[] ComputeDistances(int N, List<int[]> edges) {

        // Build adjacency list
        List<List<int>> adj = new List<List<int>>();
        for (int i = 0; i <= N; i++) adj.Add(new List<int>());
        foreach (var e in edges) {
            adj[e[0]].Add(e[1]);
            adj[e[1]].Add(e[0]);
        }

        int[] subSize = new int[N + 1];
        long[] down = new long[N + 1];
        long[] ans = new long[N + 1];

        // First DFS: compute subtree info
        Dfs1(1, 0, adj, subSize, down);

        // Set root answer
        ans[1] = down[1];

        // Second DFS: reroot and compute answers for all nodes
        Dfs2(1, 0, N, adj, subSize, ans);

        return ans;
    }

    static void Main() {
        
        
        int N = 5;
        var edges = new List<int[]> {
            new int[]{1, 2}, new int[]{1, 3},
            new int[]{3, 4}, new int[]{3, 5}
        };

        // Function call
        var result = ComputeDistances(N, edges);

        // Print output
        for (int i = 1; i <= N; i++) {
            Console.Write(result[i] + " ");
        }
    }
}
JavaScript
// First DFS: compute subSize and down values (post-order)
function dfs1(u, p, adj, subSize, down) {
    
    // Initialize subtree size and down sum for node u
    subSize[u] = 1;
    down[u] = 0;

    // Visit children
    for (let i = 0; i < adj[u].length; i++) {
        const v = adj[u][i];
        if (v === p) continue;

        dfs1(v, u, adj, subSize, down);

        // Add child's subtree size
        subSize[u] += subSize[v];

        // All nodes in child's subtree are one edge farther from u than from v
        down[u] += down[v] + subSize[v];
    }
}

// Second DFS: reroot and compute ans for all nodes (pre-order)
function dfs2(u, p, N, adj, subSize, ans) {
    
    // Visit children and reroot to compute their answers
    for (let i = 0; i < adj[u].length; i++) {
        const v = adj[u][i];
        if (v === p) continue;

        // Move root from u to v:
        // Nodes in v's subtree get 1 closer (subtract subSize[v])
        // All other nodes get 1 farther (add N - subSize[v])
        ans[v] = ans[u] - subSize[v] + (N - subSize[v]);

        dfs2(v, u, N, adj, subSize, ans);
    }
}

// Wrapper function that computes all distances
function computeDistances(N, edges) {

    // Build adjacency list
    const adj = Array.from({ length: N + 1 }, () => []);
    for (const e of edges) {
        adj[e[0]].push(e[1]);
        adj[e[1]].push(e[0]);
    }

    const subSize = new Array(N + 1).fill(0);
    const down = new Array(N + 1).fill(0);
    const ans = new Array(N + 1).fill(0);

    // First DFS: compute subtree info
    dfs1(1, 0, adj, subSize, down);

    // Set root answer
    ans[1] = down[1];

    // Second DFS: reroot and compute answers for all nodes
    dfs2(1, 0, N, adj, subSize, ans);

    return ans;
}

function main() {
    
    const N = 5;
    const edges = [[1, 2], [1, 3], [3, 4], [3, 5]];

    // Function call
    const result = computeDistances(N, edges);

    // Print output
    let out = "";
    for (let i = 1; i <= N; i++) {
        out += result[i] + " ";
    }
    console.log(out.trim());
}

main();

Output
6 9 5 8 8 

Article Tags :

Explore