Longest path in an undirected tree
Last Updated :
10 Mar, 2023
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++
// C++ program to find longest path of the tree
#include <bits/stdc++.h>
using namespace std;
// This class represents a undirected graph using adjacency list
class Graph
{
int V; // No. of vertices
list<int> *adj; // Pointer to an array containing
// adjacency lists
public:
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 u
pair<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 tree
void 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 methods
int 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
// 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#
// C# program to find longest path of the tree
using System;
using System.Collections.Generic;
class GFG
{
// Utility Pair class for storing
// maximum distance Node with its distance
public 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 list
class 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 Code
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();
}
}
// This code is contributed by Rajput-Ji
Python3
# 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()
JavaScript
<script>
// Javascript program to find longest path of the tree
// Utility Pair class for storing
// maximum distance Node with its distance
class Pair
{
// Constructor
constructor(first, second)
{
this.first = first;
this.second = second;
}
}
// This class represents a undirected graph
// using adjacency list
var V; // No. of vertices
var adj; //Adjacency List
// Constructor
function initialize(V)
{
this.V = V;
// Initializing Adjacency List
adj = Array.from(Array(V), ()=>Array());
}
// function to add an edge to graph
function 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 u
function 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 tree
function 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 example
initialize(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>
OutputLongest path is from 5 to 7 of length 5
Time Complexity: O(V+E) where V is the number of vertices and E is the number of edges.
Auxiliary Space: O(V+E)
Similar Reads
Find largest subtree sum in a tree Given a Binary Tree, the task is to find a subtree with the maximum sum in the tree.Examples: Input: Output: 28Explanation: As all the tree elements are positive, the largest subtree sum is equal to sum of all tree elements.Input: Output: 7Explanation: Subtree with largest sum is: Table of Content[E
15+ min read
Longest word in ternary search tree Given a set of words represented in a ternary search tree, find the length of largest word among them. Examples: Input : {"Prakriti", "Raghav", "Rashi", "Sunidhi"} Output : Length of largest word in ternary search tree is: 8 Input : {"Boats", "Boat", "But", "Best"} Output : Length of largest word in
11 min read
Print the longest leaf to leaf path in a Binary tree C++ // C++ program to print the longest leaf to leaf // path #include <bits/stdc++.h> using namespace std; // Tree node structure used in the program struct Node { int data; Node *left, *right; }; struct Node* newNode(int data) { struct Node* node = new Node; node->data = data; node->lef
15+ min read
Length of longest straight path from a given Binary Tree Given a Binary Tree, the task is to find the length of the longest straight path of the given binary tree. Straight Path is defined as the path that starts from any node and ends at another node in the tree such that the direction of traversal from the source node to the destination node always rema
8 min read
Longest Arithmetic Progression path in given Binary Tree Given a binary tree, the task is to find the length of the longest path which forms an Arithmetic progression. The path can start and end at any node of the tree. Examples: Input: Output: 5Explanation: The longest path forming an AP is: 3->6->9->12->15 Input: Output: 6Explanation: The lo
13 min read
Second Largest element in n-ary tree Given an n-ary tree containing positive node values, the task is to find the node with the second largest value in the given n-ary tree. If there is no second largest node return -1.Note: An n-ary tree is a tree where each node can have zero or more children nodes. Unlike a binary tree, which has at
7 min read