Farthest distance of a Node from each Node of a Tree - GeeksforGeeks

15 Jun, 2021
Given a Tree, the task is to find the farthest node from each node to another node in the given tree.
Examples  
Input: 
Output: 2 3 3 3 4 4 4 Explanation: Maximum Distance from Node 1 : 2 (Nodes {5, 6, 7} are at a distance 2) Maximum Distance from Node 2 : 3 (Nodes {6, 7} are at a distance 3) Maximum Distance from Node 3 : 3 (Nodes {5, 6, 7} are at a distance 3) Maximum Distance from Node 4 : 3 (Node {5} is at a distance 3) Maximum Distance from Node 5 : 4 (Nodes {6, 7} are at a distance 4) Maximum Distance from Node 6 : 4 (Node {5} is at a distance 4) Maximum Distance from Node 7 : 4 (Node {5} is at a distance 4)
Input: 
Output : 3 2 3 3 2 3  
Approach: 
Follow the steps below to solve the problem: 
Calculate the height of each node of the tree (Assuming the leaf nodes are at height 1) using DFS
This gives the maximum distance from a Node to all Nodes present in its Subtree. Store these heights.
Now, perform DFS to calculate the maximum distance of a Node from all its ancestors. Store these distances.
For each node, print the maximum of the two distances calculated.
Below is the implementation of the above approach:
C++
Java
Python3
C#
Javascript
// C++ Program to implement// the above approach#include <bits/stdc++.h>using namespace std; #define maxN 100001 // Adjacency List to store the graphvector<int> adj[maxN]; // Stores the height of each nodeint height[maxN]; // Stores the maximum distance of a// node from its ancestorsint dist[maxN]; // Function to add edge between// two verticesvoid addEdge(int u, int v){    // Insert edge from u to v    adj[u].push_back(v);     // Insert edge from v to u    adj[v].push_back(u);} // Function to calculate height of// each Nodevoid dfs1(int cur, int par){    // Iterate in the adjacency    // list of the current node    for (auto u : adj[cur]) {         if (u != par) {             // Dfs for child node            dfs1(u, cur);             // Calculate height of nodes            height[cur]                = max(height[cur], height[u]);        }    }     // Increase height    height[cur] += 1;} // Function to calculate the maximum// distance of a node from its ancestorvoid dfs2(int cur, int par){    int max1 = 0;    int max2 = 0;     // Iterate in the adjacency    // list of the current node    for (auto u : adj[cur]) {         if (u != par) {             // Find two children            // with maximum heights            if (height[u] >= max1) {                max2 = max1;                max1 = height[u];            }            else if (height[u] > max2) {                max2 = height[u];            }        }    }     int sum = 0;     for (auto u : adj[cur]) {        if (u != par) {             // Calculate the maximum distance            // with ancestor for every node            sum = ((max1 == height[u]) ? max2 : max1);             if (max1 == height[u])                dist[u]                    = 1 + max(1 + max2, dist[cur]);            else                dist[u]                    = 1 + max(1 + max1, dist[cur]);             // Calculating for children            dfs2(u, cur);        }    }} // Driver Codeint main(){    int n = 6;     addEdge(1, 2);    addEdge(2, 3);    addEdge(2, 4);    addEdge(2, 5);    addEdge(5, 6);     // Calculate height of    // nodes of the tree    dfs1(1, 0);     // Calculate the maximum    // distance with ancestors    dfs2(1, 0);     // Print the maximum of the two    // distances from each node    for (int i = 1; i <= n; i++)        cout << (max(dist[i], height[i]) - 1) << " ";     return 0;}
// Java program to implement// the above approachimport java.util.*; class GFG{ static final int maxN = 100001; // Adjacency List to store the graph@SuppressWarnings("unchecked")static Vector<Integer> []adj = new Vector[maxN]; // Stores the height of each nodestatic int []height = new int[maxN]; // Stores the maximum distance of a// node from its ancestorsstatic int []dist = new int[maxN]; // Function to add edge between// two verticesstatic void addEdge(int u, int v){         // Insert edge from u to v    adj[u].add(v);     // Insert edge from v to u    adj[v].add(u);} // Function to calculate height of// each Nodestatic void dfs1(int cur, int par){         // Iterate in the adjacency    // list of the current node    for(int u : adj[cur])    {        if (u != par)        {                         // Dfs for child node            dfs1(u, cur);             // Calculate height of nodes            height[cur] = Math.max(height[cur],                                   height[u]);        }    }     // Increase height    height[cur] += 1;} // Function to calculate the maximum// distance of a node from its ancestorstatic void dfs2(int cur, int par){    int max1 = 0;    int max2 = 0;     // Iterate in the adjacency    // list of the current node    for(int u : adj[cur])    {        if (u != par)        {                         // Find two children            // with maximum heights            if (height[u] >= max1)            {                max2 = max1;                max1 = height[u];            }            else if (height[u] > max2)            {                max2 = height[u];            }        }    }    int sum = 0;     for(int u : adj[cur])    {        if (u != par)        {                         // Calculate the maximum distance            // with ancestor for every node            sum = ((max1 == height[u]) ?                    max2 : max1);             if (max1 == height[u])                dist[u] = 1 + Math.max(1 + max2,                                       dist[cur]);            else                dist[u] = 1 + Math.max(1 + max1,                                       dist[cur]);             // Calculating for children            dfs2(u, cur);        }    }} // Driver Codepublic static void main(String[] args){    int n = 6;    for(int i = 0; i < adj.length; i++)        adj[i] = new Vector<Integer>();             addEdge(1, 2);    addEdge(2, 3);    addEdge(2, 4);    addEdge(2, 5);    addEdge(5, 6);     // Calculate height of    // nodes of the tree    dfs1(1, 0);     // Calculate the maximum    // distance with ancestors    dfs2(1, 0);     // Print the maximum of the two    // distances from each node    for(int i = 1; i <= n; i++)        System.out.print((Math.max(dist[i],                                 height[i]) - 1) + " ");}} // This code is contributed by 29AjayKumar
# Python3 program to implement# the above approachmaxN = 100001 # Adjacency List to store the graphadj = [[] for i in range(maxN)]  # Stores the height of each nodeheight = [0 for i in range(maxN)]  # Stores the maximum distance of a# node from its ancestorsdist = [0 for i in range(maxN)]  # Function to add edge between# two verticesdef addEdge(u, v):     # Insert edge from u to v    adj[u].append(v)      # Insert edge from v to u    adj[v].append(u) # Function to calculate height of# each Nodedef dfs1(cur, par):     # Iterate in the adjacency    # list of the current node    for u in adj[cur]:        if (u != par):              # Dfs for child node            dfs1(u, cur)              # Calculate height of nodes            height[cur] = max(height[cur],                              height[u])      # Increase height    height[cur] += 1 # Function to calculate the maximum# distance of a node from its ancestordef dfs2(cur, par):     max1 = 0    max2 = 0      # Iterate in the adjacency    # list of the current node    for u in adj[cur]:        if (u != par):              # Find two children            # with maximum heights            if (height[u] >= max1):                max2 = max1                max1 = height[u]                         elif (height[u] > max2):                max2 = height[u]      sum = 0         for u in adj[cur]:        if (u != par):              # Calculate the maximum distance            # with ancestor for every node            sum = (max2 if (max1 == height[u]) else max1)              if (max1 == height[u]):                dist[u] = 1 + max(1 + max2, dist[cur])            else:                dist[u] = 1 + max(1 + max1, dist[cur])              # Calculating for children            dfs2(u, cur)         # Driver Codeif __name__=="__main__":     n = 6      addEdge(1, 2)    addEdge(2, 3)    addEdge(2, 4)    addEdge(2, 5)    addEdge(5, 6)      # Calculate height of    # nodes of the tree    dfs1(1, 0)      # Calculate the maximum    # distance with ancestors    dfs2(1, 0)         # Print the maximum of the two    # distances from each node    for i in range(1, n + 1):        print(max(dist[i],                height[i]) - 1, end = ' ')  # This code is contributed by rutvik_56
// C# program to implement// the above approachusing System;using System.Collections.Generic; class GFG{ static readonly int maxN = 100001; // Adjacency List to store the graphstatic List<int> []adj = new List<int>[maxN]; // Stores the height of each nodestatic int []height = new int[maxN]; // Stores the maximum distance of a// node from its ancestorsstatic int []dist = new int[maxN]; // Function to add edge between// two verticesstatic void addEdge(int u, int v){         // Insert edge from u to v    adj[u].Add(v);     // Insert edge from v to u    adj[v].Add(u);} // Function to calculate height of// each Nodestatic void dfs1(int cur, int par){         // Iterate in the adjacency    // list of the current node    foreach(int u in adj[cur])    {        if (u != par)        {                         // Dfs for child node            dfs1(u, cur);             // Calculate height of nodes            height[cur] = Math.Max(height[cur],                                   height[u]);        }    }     // Increase height    height[cur] += 1;} // Function to calculate the maximum// distance of a node from its ancestorstatic void dfs2(int cur, int par){    int max1 = 0;    int max2 = 0;     // Iterate in the adjacency    // list of the current node    foreach(int u in adj[cur])    {        if (u != par)        {                         // Find two children            // with maximum heights            if (height[u] >= max1)            {                max2 = max1;                max1 = height[u];            }            else if (height[u] > max2)            {                max2 = height[u];            }        }    }    int sum = 0;     foreach(int u in adj[cur])    {        if (u != par)        {                         // Calculate the maximum distance            // with ancestor for every node            sum = ((max1 == height[u]) ?                    max2 : max1);             if (max1 == height[u])                dist[u] = 1 + Math.Max(1 + max2,                                       dist[cur]);            else                dist[u] = 1 + Math.Max(1 + max1,                                       dist[cur]);             // Calculating for children            dfs2(u, cur);        }    }} // Driver Codepublic static void Main(String[] args){    int n = 6;    for(int i = 0; i < adj.Length; i++)        adj[i] = new List<int>();             addEdge(1, 2);    addEdge(2, 3);    addEdge(2, 4);    addEdge(2, 5);    addEdge(5, 6);     // Calculate height of    // nodes of the tree    dfs1(1, 0);     // Calculate the maximum    // distance with ancestors    dfs2(1, 0);     // Print the maximum of the two    // distances from each node    for(int i = 1; i <= n; i++)        Console.Write((Math.Max(dist[i],                                height[i]) - 1) + " ");}} // This code is contributed by Rohit_ranjan
<script>     // JavaScript program to implement the above approach         let maxN = 100001;      // Adjacency List to store the graph    let adj = new Array(maxN);    adj.fill(0);     // Stores the height of each node    let height = new Array(maxN);    height.fill(0);     // Stores the maximum distance of a    // node from its ancestors    let dist = new Array(maxN);    dist.fill(0);     // Function to add edge between    // two vertices    function addEdge(u, v)    {         // Insert edge from u to v        adj[u].push(v);         // Insert edge from v to u        adj[v].push(u);    }     // Function to calculate height of    // each Node    function dfs1(cur, par)    {         // Iterate in the adjacency        // list of the current node        for(let u  = 0; u < adj[cur].length; u++)        {            if (adj[cur][u] != par)            {                 // Dfs for child node                dfs1(adj[cur][u], cur);                 // Calculate height of nodes                height[cur] = Math.max(height[cur],                                       height[adj[cur][u]]);            }        }         // Increase height        height[cur] += 1;    }     // Function to calculate the maximum    // distance of a node from its ancestor    function dfs2(cur, par)    {        let max1 = 0;        let max2 = 0;         // Iterate in the adjacency        // list of the current node        for(let u = 0; u < adj[cur].length; u++)        {            if (adj[cur][u] != par)            {                 // Find two children                // with maximum heights                if (height[adj[cur][u]] >= max1)                {                    max2 = max1;                    max1 = height[adj[cur][u]];                }                else if (height[adj[cur][u]] > max2)                {                    max2 = height[adj[cur][u]];                }            }        }        let sum = 0;         for(let u = 0; u < adj[cur].length; u++)        {            if (adj[cur][u] != par)            {                 // Calculate the maximum distance                // with ancestor for every node                sum = ((max1 == height[adj[cur][u]]) ?                        max2 : max1);                 if (max1 == height[adj[cur][u]])                    dist[adj[cur][u]] = 1 + Math.max(1 + max2,                                           dist[cur]);                else                    dist[adj[cur][u]] = 1 + Math.max(1 + max1,                                           dist[cur]);                 // Calculating for children                dfs2(adj[cur][u], cur);            }        }    }         let n = 6;    for(let i = 0; i < adj.length; i++)        adj[i] = [];              addEdge(1, 2);    addEdge(2, 3);    addEdge(2, 4);    addEdge(2, 5);    addEdge(5, 6);      // Calculate height of    // nodes of the tree    dfs1(1, 0);      // Calculate the maximum    // distance with ancestors    dfs2(1, 0);      // Print the maximum of the two    // distances from each node    for(let i = 1; i <= n; i++)        document.write((Math.max(dist[i],                                height[i]) - 1) + " "); </script>
3 2 3 3 2 3
 
Time Complexity: O(V+E) Auxiliary Space: O(N) 
29AjayKumar
Rohit_ranjan
rutvik_56
mukesh07
DFS
Tree Traversals
Trees
Dynamic Programming
Recursion
Searching
Tree
Searching
Dynamic Programming
Recursion
DFS
Tree
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Bellman–Ford Algorithm | DP-23
Floyd Warshall Algorithm | DP-16
Travelling Salesman Problem | Set 1 (Naive and Dynamic Programming)
Longest Palindromic Substring | Set 1
Matrix Chain Multiplication | DP-8
Write a program to print all permutations of a given string
Program for Tower of Hanoi
Given an array A[] and a number x, check for pair in A[] with sum as x (aka Two Sum)
Recursion
Program for Sum of the digits of a given number