Longest path in an undirected tree

07 Jul, 2022
Given an undirected tree, we need to find the longest path of this tree where a path is defined as a sequence of nodes. 
Example: 
Input : Below shown Tree using adjacency list 
        representation:
Output : 5
In below tree longest path is of length 5
from node 5 to node 7
This problem is the same as the diameter of the n-ary tree. We have discussed a simple solution here. 
In this post, an efficient solution is discussed. We can find the longest path using two BFSs. The idea is based on the following fact: If we start BFS from any node x and find a node with the longest distance from x, it must be an endpoint of the longest path. It can be proved using contradiction. So our algorithm reduces to simple two BFSs. First BFS to find an endpoint of the longest path and second BFS from this endpoint to find the actual longest path. 
For the proof of why does this algorithm works, there is a nice explanation here Proof of correctness: Algorithm for the diameter of a tree in graph theory 
As we can see in the above diagram, if we start our BFS from node-0, the node at the farthest distance from it will be node-5, now if we start our BFS from node-5 the node at the farthest distance will be node-7, finally, the path from node-5 to node-7 will constitute our longest path.
Implementation:
C++
Java
C#
Python3
Javascript
// C++ program to find longest path of the tree#include <bits/stdc++.h>using namespace std; // This class represents a undirected graph using adjacency listclass Graph{    int V;              // No. of vertices    list<int> *adj;     // Pointer to an array containing                        // adjacency listspublic:    Graph(int V);              // Constructor    void addEdge(int v, int w);// function to add an edge to graph    void longestPathLength();  // prints longest path of the tree    pair<int, int> bfs(int u); // function returns maximum distant                               // node from u with its distance}; Graph::Graph(int V){    this->V = V;    adj = new list<int>[V];} void Graph::addEdge(int v, int w){    adj[v].push_back(w);    // Add w to v’s list.    adj[w].push_back(v);    // Since the graph is undirected} //  method returns farthest node and its distance from node upair<int, int> Graph::bfs(int u){    //  mark all distance with -1    int dis[V];    memset(dis, -1, sizeof(dis));     queue<int> q;    q.push(u);     //  distance of u from u will be 0    dis[u] = 0;     while (!q.empty())    {        int t = q.front();       q.pop();         //  loop for all adjacent nodes of node-t        for (auto it = adj[t].begin(); it != adj[t].end(); it++)        {            int v = *it;             // push node into queue only if            // it is not visited already            if (dis[v] == -1)            {                q.push(v);                 // make distance of v, one more                // than distance of t                dis[v] = dis[t] + 1;            }        }    }     int maxDis = 0;    int nodeIdx;     //  get farthest node distance and its index    for (int i = 0; i < V; i++)    {        if (dis[i] > maxDis)        {            maxDis = dis[i];            nodeIdx = i;        }    }    return make_pair(nodeIdx, maxDis);} //  method prints longest path of given treevoid Graph::longestPathLength(){    pair<int, int> t1, t2;     // first bfs to find one end point of    // longest path    t1 = bfs(0);     //  second bfs to find actual longest path    t2 = bfs(t1.first);     cout << "Longest path is from " << t1.first << " to "         << t2.first << " of length " << t2.second;} // Driver code to test above methodsint main(){    // Create a graph given in the example    Graph g(10);    g.addEdge(0, 1);    g.addEdge(1, 2);    g.addEdge(2, 3);    g.addEdge(2, 9);    g.addEdge(2, 4);    g.addEdge(4, 5);    g.addEdge(1, 6);    g.addEdge(6, 7);    g.addEdge(6, 8);     g.longestPathLength();    return 0;}
// Java program to find longest path of the tree import java.util.Arrays;import java.util.LinkedList;import java.util.Queue;  class LongestPathUndirectedTree {         // Utility Pair class for storing maximum distance    // Node with its distance    static class Pair<T,V> {        T first; // maximum distance Node        V second; // distance of maximum distance node                 //Constructor        Pair(T first, V second) {            this.first = first;            this.second = second;        }    }         // This class represents a undirected graph using adjacency list    static class Graph {        int V; // No. of vertices        LinkedList<Integer>[] adj; //Adjacency List                 // Constructor        Graph(int V) {            this.V = V;            // Initializing Adjacency List            adj = new LinkedList[V];            for(int i = 0; i < V; ++i) {                adj[i] = new LinkedList<Integer>();            }        }                 // function to add an edge to graph        void addEdge(int s, int d) {            adj[s].add(d); // Add d to s's list.            adj[d].add(s); // Since the graph is undirected        }                          // method returns farthest node and its distance from node u        Pair<Integer, Integer> bfs(int u) {            int[] dis = new int[V];                         // mark all distance with -1            Arrays.fill(dis, -1);             Queue<Integer> q = new LinkedList<>();             q.add(u);                         // distance of u from u will be 0            dis[u] = 0;            while (!q.isEmpty()) {                int t = q.poll();                                 // loop for all adjacent nodes of node-t                for(int i = 0; i < adj[t].size(); ++i) {                    int v = adj[t].get(i);                                         // push node into queue only if                    // it is not visited already                    if(dis[v] == -1) {                        q.add(v);                        // make distance of v, one more                        // than distance of t                        dis[v] = dis[t] + 1;                    }                }            }             int maxDis = 0;            int nodeIdx = 0;                         // get farthest node distance and its index            for(int i = 0; i < V; ++i) {                if(dis[i] > maxDis) {                    maxDis = dis[i];                    nodeIdx = i;                }            }             return new Pair<Integer, Integer>(nodeIdx, maxDis);        }                 // method prints longest path of given tree        void longestPathLength() {            Pair<Integer, Integer> t1, t2;                         // first bfs to find one end point of            // longest path            t1 = bfs(0);                         // second bfs to find actual longest path            t2 = bfs(t1.first);             System.out.println("Longest path is from "+ t1.first            + " to "+ t2.first +" of length "+t2.second);        }    }         // Driver code to test above methods    public static void main(String[] args){        // Create a graph given in the example                 Graph graph = new Graph(10);        graph.addEdge(0, 1);        graph.addEdge(1, 2);        graph.addEdge(2, 3);        graph.addEdge(2, 9);        graph.addEdge(2, 4);        graph.addEdge(4, 5);        graph.addEdge(1, 6);        graph.addEdge(6, 7);        graph.addEdge(6, 8);         graph.longestPathLength();    } }// Added By Brij Raj Kishore
// C# program to find longest path of the treeusing System;using System.Collections.Generic; class GFG{     // Utility Pair class for storing// maximum distance Node with its distancepublic class Pair<T, V>{    // maximum distance Node    public T first;         // distance of maximum distance node    public V second;         // Constructor    public Pair(T first, V second)    {        this.first = first;        this.second = second;    }} // This class represents a undirected graph// using adjacency listclass Graph{    int V; // No. of vertices    List<int>[] adj; //Adjacency List         // Constructor    public Graph(int V)    {        this.V = V;                 // Initializing Adjacency List        adj = new List<int>[V];        for(int i = 0; i < V; ++i)        {            adj[i] = new List<int>();        }    }         // function to add an edge to graph    public void addEdge(int s, int d)    {        adj[s].Add(d); // Add d to s's list.        adj[d].Add(s); // Since the graph is undirected    }         // method returns farthest node and    // its distance from node u    public Pair<int, int> bfs(int u)    {        int[] dis = new int[V];                 // mark all distance with -1        for(int i = 0; i < V; i++)            dis[i] = -1;         Queue<int> q = new Queue<int>();         q.Enqueue(u);                 // distance of u from u will be 0        dis[u] = 0;        while (q.Count != 0)        {            int t = q.Dequeue();                         // loop for all adjacent nodes of node-t            for(int i = 0; i < adj[t].Count; ++i)            {                int v = adj[t][i];                                 // push node into queue only if                // it is not visited already                if(dis[v] == -1)                {                    q.Enqueue(v);                                         // make distance of v, one more                    // than distance of t                    dis[v] = dis[t] + 1;                }            }        }        int maxDis = 0;        int nodeIdx = 0;                 // get farthest node distance and its index        for(int i = 0; i < V; ++i)        {            if(dis[i] > maxDis)            {                maxDis = dis[i];                nodeIdx = i;            }        }        return new Pair<int, int>(nodeIdx, maxDis);    }         // method prints longest path of given tree    public void longestPathLength()    {        Pair<int, int> t1, t2;                 // first bfs to find one end point of        // longest path        t1 = bfs(0);                 // second bfs to find actual longest path        t2 = bfs(t1.first);         Console.WriteLine("longest path is from " + t1.first +                " to " + t2.first + " of length " + t2.second);    }} // Driver Codepublic static void Main(String[] args){        // Create a graph given in the example    Graph graph = new Graph(10);    graph.addEdge(0, 1);    graph.addEdge(1, 2);    graph.addEdge(2, 3);    graph.addEdge(2, 9);    graph.addEdge(2, 4);    graph.addEdge(4, 5);    graph.addEdge(1, 6);    graph.addEdge(6, 7);    graph.addEdge(6, 8);     graph.longestPathLength();}} // This code is contributed by Rajput-Ji
# Python program to find the Longest Path of the Tree# By Aaditya Upadhyay from collections import deque  class Graph:     # Initialisation of graph    def __init__(self, vertices):         # No. of vertices        self.vertices = vertices         # adjacency list        self.adj = {i: [] for i in range(self.vertices)}     def addEdge(self, u, v):        # add u to v's list        self.adj[u].append(v)        # since the graph is undirected        self.adj[v].append(u)     # method return farthest node and its distance from node u    def BFS(self, u):        # marking all nodes as unvisited        visited = [False for i in range(self.vertices + 1)]        # mark all distance with -1        distance = [-1 for i in range(self.vertices + 1)]         # distance of u from u will be 0        distance[u] = 0        # in-built library for queue which performs fast operations on both the ends        queue = deque()        queue.append(u)        # mark node u as visited        visited[u] = True         while queue:             # pop the front of the queue(0th element)            front = queue.popleft()            # loop for all adjacent nodes of node front             for i in self.adj[front]:                if not visited[i]:                    # mark the ith node as visited                    visited[i] = True                    # make distance of i , one more than distance of front                    distance[i] = distance[front]+1                    # Push node into the stack only if it is not visited already                    queue.append(i)         maxDis = 0         # get farthest node distance and its index        for i in range(self.vertices):            if distance[i] > maxDis:                 maxDis = distance[i]                nodeIdx = i         return nodeIdx, maxDis     # method prints longest path of given tree    def LongestPathLength(self):         # first DFS to find one end point of longest path        node, Dis = self.BFS(0)         # second DFS to find the actual longest path        node_2, LongDis = self.BFS(node)         print('Longest path is from', node, 'to', node_2, 'of length', LongDis)  # create a graph given in the example G = Graph(10)G.addEdge(0, 1)G.addEdge(1, 2)G.addEdge(2, 3)G.addEdge(2, 9)G.addEdge(2, 4)G.addEdge(4, 5)G.addEdge(1, 6)G.addEdge(6, 7)G.addEdge(6, 8) G.LongestPathLength()
<script> // Javascript program to find longest path of the tree      // Utility Pair class for storing// maximum distance Node with its distanceclass Pair{    // Constructor    constructor(first, second)    {        this.first = first;        this.second = second;    }} // This class represents a undirected graph// using adjacency listvar V; // No. of verticesvar adj; //Adjacency List // Constructorfunction initialize(V){    this.V = V;         // Initializing Adjacency List    adj = Array.from(Array(V), ()=>Array());} // function to add an edge to graphfunction addEdge(s, d){    adj[s].push(d); // push d to s's list.    adj[d].push(s); // Since the graph is undirected} // method returns farthest node and// its distance from node ufunction bfs(u){    var dis = Array(V);         // mark all distance with -1    for(var i = 0; i < V; i++)        dis[i] = -1;    var q = [];    q.push(u);         // distance of u from u will be 0    dis[u] = 0;    while (q.length != 0)    {        var t = q.shift();                 // loop for all adjacent nodes of node-t        for(var i = 0; i < adj[t].length; ++i)        {            var v = adj[t][i];                         // push node into queue only if            // it is not visited already            if(dis[v] == -1)            {                q.push(v);                                 // make distance of v, one more                // than distance of t                dis[v] = dis[t] + 1;            }        }    }    var maxDis = 0;    var nodeIdx = 0;         // get farthest node distance and its index    for(var i = 0; i < V; ++i)    {        if(dis[i] > maxDis)        {            maxDis = dis[i];            nodeIdx = i;        }    }    return new Pair(nodeIdx, maxDis);} // method prints longest path of given treefunction longestPathLength(){    var t1, t2;         // first bfs to find one end point of    // longest path    t1 = bfs(0);         // second bfs to find actual longest path    t2 = bfs(t1.first);    document.write("longest path is from " + t1.first +            " to " + t2.first + " of length " + t2.second);}  // Create a graph given in the exampleinitialize(10)addEdge(0, 1);addEdge(1, 2);addEdge(2, 3);addEdge(2, 9);addEdge(2, 4);addEdge(4, 5);addEdge(1, 6);addEdge(6, 7);addEdge(6, 8);longestPathLength(); // This code is contributed by famously.</script>
Longest path is from 5 to 7 of length 5
This article is contributed by Utkarsh Trivedi. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks. 
Brij Raj Kishore
Rajput-Ji
aadiupadhyay
gabaa406
saurabh1990aror
famously
hardikkoriintern
BFS
n-ary-tree
Tree
Tree
BFS
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Introduction to Data Structures
Introduction to Tree Data Structure
What is Data Structure: Types, Classifications and Applications
Binary Tree | Set 2 (Properties)
Lowest Common Ancestor in a Binary Tree | Set 1
Decision Tree
Diagonal Traversal of Binary Tree
Construct Tree from given Inorder and Preorder traversals
Insertion in a Binary Tree in level order
Print Left View of a Binary Tree