# DP on Trees | Set-3 ( Diameter of N-ary Tree )

• Difficulty Level : Medium
• Last Updated : 28 Apr, 2022

Given an N-ary tree T of N nodes, the task is to calculate the longest path between any two nodes(also known as the diameter of the tree).
Example 1:

Example 2:

Different approaches to solve these problems have already been discussed:

In this post, we will be discussing an approach which uses Dynamic Programming on Trees
Prerequisites

There are two possibilities for the diameter to exist:

• Case 1: Suppose the diameter starts from a node and ends at some node in its subtree. Let’s say that there exist a node x such that the longest path starts from node x and goes into its subtree and ends at some node in the subtree itself. Let’s define this path length by dp1[x].
• Case 2: Suppose the diameter or the longest path starts in subtree of a node x, passes through it and ends in it’s subtree. Let’s define this path by dp2[x].

If for all nodes x, we take a maximum of dp1[x], dp2[x], then we will get the diameter of the tree.
For the case-1, to find dp1[node], we need to find the maximum of all dp1[x], where x is the children of node. And dp1[node] will be equal to 1 + max(dp1[children1], dp1[children2], ..)
For the case-2, to find dp2[node], we need to find the two maximum of all dp1[x], where x is the children of node. And dp2[node] will be equal to 1 + max 2 of(dp1[children1], dp1[children2], ..) + max(dp1[children1], dp1[children2], ..). This will ensure a complete path passing through the current node into its subtree.
We can easily run a DFS and find the maximum of both dp1[node] and dp2[node] for every to get the diameter of the tree.
Below is the implementation of the above approach:

## C++

 `// C++ program to find diameter of a tree ` `// using DFS. ` `#include ` `using` `namespace` `std; ` ` `  `int` `diameter = -1; ` ` `  `// Function to find the diameter of the tree ` `// using Dynamic Programming ` `int` `dfs(``int` `node, ``int` `parent, ``int` `dp1[], ``int` `dp2[], list<``int``>* adj) ` `{ ` ` `  `    ``// Store the first maximum and secondmax ` `    ``int` `firstmax = -1; ` `    ``int` `secondmax = -1; ` ` `  `    ``// Traverse for all children of node ` `    ``for` `(``auto` `i = adj[node].begin(); i != adj[node].end(); ++i) { ` `        ``if` `(*i == parent) ` `            ``continue``; ` ` `  `        ``// Call DFS function again ` `        ``dfs(*i, node, dp1, dp2, adj); ` ` `  `        ``// Find first max ` `        ``if` `(firstmax == -1) { ` `            ``firstmax = dp1[*i]; ` `        ``} ` `        ``else` `if` `(dp1[*i] >= firstmax) ``// Secondmaximum ` `        ``{ ` `            ``secondmax = firstmax; ` `            ``firstmax = dp1[*i]; ` `        ``} ` `        ``else` `if` `(dp1[*i] > secondmax) ``// Find secondmaximum ` `        ``{ ` `            ``secondmax = dp1[*i]; ` `        ``} ` `    ``} ` ` `  `    ``// Base case for every node ` `    ``dp1[node] = 1; ` `    ``if` `(firstmax != -1) ``// Add ` `        ``dp1[node] += firstmax; ` ` `  `    ``// Find dp[2] ` `    ``if` `(secondmax != -1) ` `        ``dp2[node] = 1 + firstmax + secondmax; ` ` `  `    ``diameter = max(diameter, max(dp1[node], dp2[node])); ` `    ``// Return maximum of both ` `    ``return` `max(dp1[node], dp2[node]); ` `} ` ` `  `// Driver Code ` `int` `main() ` `{ ` `    ``int` `n = 5; ` ` `  `    ``/* Constructed tree is  ` `         ``1  ` `        ``/ \  ` `        ``2 3  ` `       ``/ \  ` `       ``4  5 */` `    ``list<``int``>* adj = ``new` `list<``int``>[n + 1]; ` ` `  `    ``/*create undirected edges */` `    ``adj[1].push_back(2); ` `    ``adj[2].push_back(1); ` `    ``adj[1].push_back(3); ` `    ``adj[3].push_back(1); ` `    ``adj[2].push_back(4); ` `    ``adj[4].push_back(2); ` `    ``adj[2].push_back(5); ` `    ``adj[5].push_back(2); ` ` `  `    ``int` `dp1[n + 1], dp2[n + 1]; ` `    ``memset``(dp1, 0, ``sizeof` `dp1); ` `    ``memset``(dp2, 0, ``sizeof` `dp2); ` ` `  `    ``// Find diameter by calling function ` `    ``dfs(1, 1, dp1, dp2, adj) ` `    ``cout << ``"Diameter of the given tree is "` `         ``<< diameter << endl; ` ` `  `    ``return` `0; ` `} `

## Java

 `// Java program to find diameter of a tree using DFS. ` `import` `java.util.*; ` `public` `class` `Main ` `{ ` `    ``// Function to find the diameter of the tree ` `    ``// using Dynamic Programming ` `    ``static` `int` `dfs(``int` `node, ``int` `parent, ``int``[] dp1, ``int``[] dp2, Vector> adj) ` `    ``{ ` `   `  `        ``// Store the first maximum and secondmax ` `        ``int` `firstmax = -``1``; ` `        ``int` `secondmax = -``1``; ` `   `  `        ``// Traverse for all children of node ` `        ``for` `(``int` `i = ``0``; i < adj.get(node).size(); ++i) { ` `            ``if` `(adj.get(node).get(i) == parent) ` `                ``continue``; ` `   `  `            ``// Call DFS function again ` `            ``dfs(adj.get(node).get(i), node, dp1, dp2, adj); ` `   `  `            ``// Find first max ` `            ``if` `(firstmax == -``1``) { ` `                ``firstmax = dp1[adj.get(node).get(i)]; ` `            ``} ` `            ``// Secondmaximum ` `            ``else` `if` `(dp1[adj.get(node).get(i)] >= firstmax) ` `            ``{ ` `                ``secondmax = firstmax; ` `                ``firstmax = dp1[adj.get(node).get(i)]; ` `            ``} ` `            ``// Find secondmaximum ` `            ``else` `if` `(dp1[adj.get(node).get(i)] > secondmax) ` `            ``{ ` `                ``secondmax = dp1[adj.get(node).get(i)]; ` `            ``} ` `        ``} ` `   `  `        ``// Base case for every node ` `        ``dp1[node] = ``1``; ` `        ``if` `(firstmax != -``1``) ``// Add ` `            ``dp1[node] += firstmax; ` `   `  `        ``// Find dp[2] ` `        ``if` `(secondmax != -``1``) ` `            ``dp2[node] = ``1` `+ firstmax + secondmax; ` `   `  `        ``// Return maximum of both ` `        ``return` `Math.max(dp1[node], dp2[node]); ` `    ``} ` `     `  `    ``public` `static` `void` `main(String[] args) { ` `        ``int` `n = ``5``; ` `   `  `        ``/* Constructed tree is ` `             ``1 ` `            ``/ \ ` `            ``2 3 ` `           ``/ \ ` `           ``4  5 */` `        ``Vector> adj = ``new` `Vector>(); ` `          `  `        ``for``(``int` `i = ``0``; i < n + ``1``; i++) ` `        ``{ ` `            ``adj.add(``new` `Vector()); ` `        ``} ` `       `  `        ``/*create undirected edges */` `        ``adj.get(``1``).add(``2``); ` `        ``adj.get(``2``).add(``1``); ` `        ``adj.get(``1``).add(``3``); ` `        ``adj.get(``3``).add(``1``); ` `        ``adj.get(``2``).add(``4``); ` `        ``adj.get(``4``).add(``2``); ` `        ``adj.get(``2``).add(``5``); ` `        ``adj.get(``5``).add(``2``); ` `       `  `        ``int``[] dp1 = ``new` `int``[n + ``1``]; ` `        ``int``[] dp2 = ``new` `int``[n + ``1``]; ` `          `  `        ``for``(``int` `i = ``0``; i < n + ``1``; i++) ` `        ``{ ` `            ``dp1[i] = ``0``; ` `            ``dp2[i] = ``0``; ` `        ``} ` `       `  `        ``// Find diameter by calling function ` `        ``System.out.println(``"Diameter of the given tree is "` `             ``+ dfs(``1``, ``1``, dp1, dp2, adj)); ` `    ``} ` `} ` ` `  `// This code is contributed by divyeshrabadiya07.`

## Python3

 `# Python3 program to find diameter  ` `# of a tree using DFS.  ` ` `  `# Function to find the diameter of the  ` `# tree using Dynamic Programming  ` `def` `dfs(node, parent, dp1, dp2, adj):  ` ` `  `    ``# Store the first maximum and secondmax  ` `    ``firstmax, secondmax ``=` `-``1``, ``-``1` ` `  `    ``# Traverse for all children of node  ` `    ``for` `i ``in` `adj[node]:  ` `        ``if` `i ``=``=` `parent:  ` `            ``continue` ` `  `        ``# Call DFS function again  ` `        ``dfs(i, node, dp1, dp2, adj)  ` ` `  `        ``# Find first max  ` `        ``if` `firstmax ``=``=` `-``1``:  ` `            ``firstmax ``=` `dp1[i]  ` `         `  `        ``elif` `dp1[i] >``=` `firstmax: ``# Secondmaximum  ` `            ``secondmax ``=` `firstmax  ` `            ``firstmax ``=` `dp1[i]  ` `         `  `        ``elif` `dp1[i] > secondmax: ``# Find secondmaximum  ` `            ``secondmax ``=` `dp1[i]  ` ` `  `    ``# Base case for every node  ` `    ``dp1[node] ``=` `1` `    ``if` `firstmax !``=` `-``1``: ``# Add  ` `        ``dp1[node] ``+``=` `firstmax  ` ` `  `    ``# Find dp[2]  ` `    ``if` `secondmax !``=` `-``1``: ` `        ``dp2[node] ``=` `1` `+` `firstmax ``+` `secondmax  ` `    ``diameter ``=` `max``(diameter, ``max``(dp1[node], dp2[node])); ` `    ``# Return maximum of both  ` `    ``return` `max``(dp1[node], dp2[node])  ` ` `  `# Driver Code  ` `if` `__name__ ``=``=` `"__main__"``: ` ` `  `    ``n, diameter ``=` `5``, ``-``1` ` `  `    ``adj ``=` `[[] ``for` `i ``in` `range``(n ``+` `1``)] ` `     `  `    ``# create undirected edges ` `    ``adj[``1``].append(``2``)  ` `    ``adj[``2``].append(``1``)  ` `    ``adj[``1``].append(``3``)  ` `    ``adj[``3``].append(``1``)  ` `    ``adj[``2``].append(``4``)  ` `    ``adj[``4``].append(``2``)  ` `    ``adj[``2``].append(``5``)  ` `    ``adj[``5``].append(``2``)  ` ` `  `    ``dp1 ``=` `[``0``] ``*` `(n ``+` `1``)  ` `    ``dp2 ``=` `[``0``] ``*` `(n ``+` `1``)  ` `     `  `    ``# Find diameter by calling function  ` `    ``dfs(``1``, ``1``, dp1, dp2, adj) ` `    ``print``(``"Diameter of the given tree is"``, ` `                ``diameter ) ` ` `  `# This code is contributed by Rituraj Jain  `

## C#

 `// C# program to find diameter of a tree using DFS. ` `using` `System; ` `using` `System.Collections.Generic; ` `class` `GFG { ` `    `  `    ``// Function to find the diameter of the tree ` `    ``// using Dynamic Programming ` `    ``static` `int` `dfs(``int` `node, ``int` `parent, ``int``[] dp1, ``int``[] dp2, List> adj) ` `    ``{ ` `  `  `        ``// Store the first maximum and secondmax ` `        ``int` `firstmax = -1; ` `        ``int` `secondmax = -1; ` `  `  `        ``// Traverse for all children of node ` `        ``for` `(``int` `i = 0; i < adj[node].Count; ++i) { ` `            ``if` `(adj[node][i] == parent) ` `                ``continue``; ` `  `  `            ``// Call DFS function again ` `            ``dfs(adj[node][i], node, dp1, dp2, adj); ` `  `  `            ``// Find first max ` `            ``if` `(firstmax == -1) { ` `                ``firstmax = dp1[adj[node][i]]; ` `            ``} ` `            ``// Secondmaximum ` `            ``else` `if` `(dp1[adj[node][i]] >= firstmax) ` `            ``{ ` `                ``secondmax = firstmax; ` `                ``firstmax = dp1[adj[node][i]]; ` `            ``} ` `            ``// Find secondmaximum ` `            ``else` `if` `(dp1[adj[node][i]] > secondmax) ` `            ``{ ` `                ``secondmax = dp1[adj[node][i]]; ` `            ``} ` `        ``} ` `  `  `        ``// Base case for every node ` `        ``dp1[node] = 1; ` `        ``if` `(firstmax != -1) ``// Add ` `            ``dp1[node] += firstmax; ` `  `  `        ``// Find dp[2] ` `        ``if` `(secondmax != -1) ` `            ``dp2[node] = 1 + firstmax + secondmax; ` `         `  `        ``// diameter = Math.Max(diameter, Math.Max(dp1[node], dp2[node])); ` `        ``// Return maximum of both ` `        ``return` `Math.Max(dp1[node], dp2[node]); ` `    ``} ` ` `  `  ``static` `void` `Main() { ` `    ``int` `n = 5; ` `  `  `    ``/* Constructed tree is ` `         ``1 ` `        ``/ \ ` `        ``2 3 ` `       ``/ \ ` `       ``4  5 */` `    ``List> adj = ``new` `List>(); ` `     `  `    ``for``(``int` `i = 0; i < n + 1; i++) ` `    ``{ ` `        ``adj.Add(``new` `List<``int``>()); ` `    ``} ` `  `  `    ``/*create undirected edges */` `    ``adj[1].Add(2); ` `    ``adj[2].Add(1); ` `    ``adj[1].Add(3); ` `    ``adj[3].Add(1); ` `    ``adj[2].Add(4); ` `    ``adj[4].Add(2); ` `    ``adj[2].Add(5); ` `    ``adj[5].Add(2); ` `  `  `    ``int``[] dp1 = ``new` `int``[n + 1]; ` `    ``int``[] dp2 = ``new` `int``[n + 1]; ` `     `  `    ``for``(``int` `i = 0; i < n + 1; i++) ` `    ``{ ` `        ``dp1[i] = 0; ` `        ``dp2[i] = 0; ` `    ``} ` `  `  `    ``// Find diameter by calling function ` `     `  `    ``Console.WriteLine(``"Diameter of the given tree is "` `         ``+ dfs(1, 1, dp1, dp2, adj)); ` `  ``} ` `} ` ` `  `// This code is contributed by decode2207.`

## Javascript

 ``

Output:

`Diameter of the given tree is 4`

Time Complexity: O(n)

Auxiliary Space: O(n)

My Personal Notes arrow_drop_up
Recommended Articles
Page :