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

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:

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

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], ..).

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; ` ` `  `    ``// 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 ` `    ``cout << ``"Diameter of the given tree is "` `         ``<< dfs(1, 1, dp1, dp2, adj) << endl; ` ` `  `    ``return` `0; ` `} `

## 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
if i == parent:
continue

# Call DFS function again

# 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

# 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

dp1 = [0] * (n + 1)
dp2 = [0] * (n + 1)

# Find diameter by calling function
print(“Diameter of the given tree is”,
```Diameter of the given tree is 4