Given a N-ary tree with a value associated with each node, the task is to choose a subset of these nodes such that sum of chosen nodes is maximum under a constraint that no two chosen node in subset should be directly connected that is, if we have taken a node in our sum then we can’t take its any children in consideration and vice versa.**Examples:**

The above diagram selects the nodes with a deep green color to get the maximum value 25.

An approach to this problem has been discussed in the previous post using recursion.

In this post, we will be discussing an approach using Dynamic Programming on Trees.

While solving the problem, there arise two cases:

- For a particular node, the maximum sum can be calculated by including the node itself along with nodes from its subtree.
- Or, the maximum sum is calculated by excluding the current node and including only the nodes from its subtree.

**Let us assume**:

**dp1[node]**to be the maximum possible sum by choosing nodes from the subtree of this node and also including the node.- And,
**dp2[node]**to be the maximum possible sum by choosing nodes from the subtree of the node and not including the node itself.

In the first case, if we include the current node, then its value is added and then we can not include any of its immediate children, hence the summation of dp2[] of all the children will be taken into the count to compute dp1[node]. That is,

dp1[node]= tree[node] + sum(dp2[children1], dp2[children2], …)

In the second case, if we do not include the current node, then its value is not added, but the children node can be taken or it cannot be taken, hence the summation of the maximum of both for all the children will be taken into count to compute dp2[node]. That is,

dp2[node]= tree[node] + sum(max(dp1[children1], dp2[children1]), max(dp1[children2], dp2[children2])…)

In the end, the final answer will be the maximum of dp1[root] and dp2[root].

Below is the implementation of the above approach:

## C++

`// C++ program to find maximum sum` `// of a subset of nodes that are not adjacent` `#include <bits/stdc++.h>` `using` `namespace` `std;` `// Function to find the diameter of the tree` `// using Dynamic Programming` `void` `dfs(` `int` `node, ` `int` `parent, ` `int` `dp1[], ` `int` `dp2[],` ` ` `list<` `int` `>* adj, ` `int` `tree[])` `{` ` ` `int` `sum1 = 0, sum2 = 0;` ` ` `// 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, tree);` ` ` `// Include the current node` ` ` `// then donot include the children` ` ` `sum1 += dp2[*i];` ` ` `// Donot include current node,` ` ` `// then include children or not include them` ` ` `sum2 += max(dp1[*i], dp2[*i]);` ` ` `}` ` ` `// Recurrence value` ` ` `dp1[node] = tree[node] + sum1;` ` ` `dp2[node] = sum2;` `}` `/* Driver program to test above functions */` `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);` ` ` `// Numbers to node` ` ` `int` `tree[n + 1];` ` ` `tree[1] = 10;` ` ` `tree[2] = 5;` ` ` `tree[3] = 11;` ` ` `tree[4] = 6;` ` ` `tree[5] = 8;` ` ` `int` `dp1[n + 1], dp2[n + 1];` ` ` `memset` `(dp1, 0, ` `sizeof` `dp1);` ` ` `memset` `(dp2, 0, ` `sizeof` `dp2);` ` ` `dfs(1, 1, dp1, dp2, adj, tree);` ` ` `// Find maximum sum by calling function` ` ` `cout << ` `"Maximum sum: "` ` ` `<< max(dp1[1], dp2[1]) << endl;` ` ` `return` `0;` `}` |

*chevron_right*

*filter_none*

## Python3

`# Python3 program to find ` `# maximum sum of a subset ` `# of nodes that are not ` `# adjacent` `# Function to find the diameter` `# of the tree using Dynamic ` `# Programming` `def` `dfs(node, parent, dp1, ` ` ` `dp2, adj, tree):` ` ` ` ` `sum1 ` `=` `0` ` ` `sum2 ` `=` `0` ` ` ` ` `# 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, tree);` ` ` ` ` `# Include the current ` ` ` `# node then donot include ` ` ` `# the children` ` ` `sum1 ` `+` `=` `dp2[i];` ` ` ` ` `# Donot include current node,` ` ` `# then include children or not ` ` ` `# include them` ` ` `sum2 ` `+` `=` `max` `(dp1[i], ` ` ` `dp2[i]); ` ` ` ` ` `# Recurrence value` ` ` `dp1[node] ` `=` `tree[node] ` `+` `sum1;` ` ` `dp2[node] ` `=` `sum2;` `# Driver code` `if` `__name__` `=` `=` `"__main__"` `:` ` ` ` ` `n ` `=` `5` `;` ` ` ` ` `''' Constructed tree is ` ` ` `1 ` ` ` `/ \ ` ` ` `2 3 ` ` ` `/ \ ` ` ` `4 5 '''` ` ` ` ` `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` `);` ` ` ` ` `# Numbers to node` ` ` `tree ` `=` `[` `0` `for` `i ` `in` `range` `(n ` `+` `1` `)];` ` ` `tree[` `1` `] ` `=` `10` `;` ` ` `tree[` `2` `] ` `=` `5` `;` ` ` `tree[` `3` `] ` `=` `11` `;` ` ` `tree[` `4` `] ` `=` `6` `;` ` ` `tree[` `5` `] ` `=` `8` `;` ` ` ` ` `dp1 ` `=` `[` `0` `for` `i ` `in` `range` `(n ` `+` `1` `)];` ` ` `dp2 ` `=` `[` `0` `for` `i ` `in` `range` `(n ` `+` `1` `)];` ` ` ` ` `dfs(` `1` `, ` `1` `, dp1, dp2, adj, tree);` ` ` ` ` `# Find maximum sum by calling ` ` ` `# function` ` ` `print` `(` `"Maximum sum:"` `,` ` ` `max` `(dp1[` `1` `], dp2[` `1` `]))` ` ` `# This code is contributed by Rutvik_56` |

*chevron_right*

*filter_none*

## C#

`// C# program to find maximum sum` `// of a subset of nodes that are not adjacent` `using` `System;` `using` `System.Collections;` `class` `GFG` `{` `// Function to find the diameter of the tree` `// using Dynamic Programming` `public` `static` `void` `dfs(` `int` `node, ` `int` `parent, ` `int` `[]dp1, ` `int` `[]dp2,` ` ` `ArrayList []adj, ` `int` `[]tree)` `{` ` ` ` ` `int` `sum1 = 0, sum2 = 0;` ` ` ` ` `// Traverse for all children of node` ` ` `foreach` `(` `int` `i ` `in` `adj[node])` ` ` `{` ` ` `if` `(i == parent)` ` ` `continue` `;` ` ` ` ` `// Call DFS function again` ` ` `dfs(i, node, dp1, dp2, adj, tree);` ` ` ` ` `// Include the current node` ` ` `// then donot include the children` ` ` `sum1 += dp2[i];` ` ` ` ` `// Donot include current node,` ` ` `// then include children or not include them` ` ` `sum2 += Math.Max(dp1[i], dp2[i]);` ` ` `}` ` ` ` ` `// Recurrence value` ` ` `dp1[node] = tree[node] + sum1;` ` ` `dp2[node] = sum2;` `}` ` ` `/* Driver program to test above functions */` `public` `static` `void` `Main(` `string` `[]arg)` `{` ` ` `int` `n = 5;` ` ` ` ` `/* Constructed tree is ` ` ` `1 ` ` ` `/ \ ` ` ` `2 3 ` ` ` `/ \ ` ` ` `4 5 */` ` ` `ArrayList []adj = ` `new` `ArrayList[n + 1];` ` ` ` ` `for` `(` `int` `i = 0; i < n + 1; i++)` ` ` `{` ` ` `adj[i] = ` `new` `ArrayList();` ` ` `}` ` ` ` ` `/* 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);` ` ` ` ` `// Numbers to node` ` ` `int` `[]tree = ` `new` `int` `[n + 1];` ` ` `tree[1] = 10;` ` ` `tree[2] = 5;` ` ` `tree[3] = 11;` ` ` `tree[4] = 6;` ` ` `tree[5] = 8;` ` ` ` ` `int` `[]dp1 = ` `new` `int` `[n + 1];` ` ` `int` `[]dp2 = ` `new` `int` `[n + 1];` ` ` `Array.Fill(dp1, 0);` ` ` `Array.Fill(dp2, 0);` ` ` ` ` `dfs(1, 1, dp1, dp2, adj, tree);` ` ` ` ` `// Find maximum sum by calling function` ` ` `Console.Write(` `"Maximum sum: "` `+ Math.Max(dp1[1], dp2[1]));` `}` `}` `// This code is contributed by pratham76` |

*chevron_right*

*filter_none*

**Output:**

Maximum sum: 25

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the **DSA Self Paced Course** at a student-friendly price and become industry ready.

## Recommended Posts:

- Maximum sum of nodes in Binary tree such that no two are adjacent
- Maximum sub-tree sum in a Binary Tree such that the sub-tree is also a BST
- Maximum sum such that no two elements are adjacent
- Maximum sum in a 2 x n grid such that no two elements are adjacent
- Maximum sum in circular array such that no two elements are adjacent
- Maximum sum such that no two elements are adjacent | Set 2
- Maximum sub-sequence sum such that indices of any two adjacent elements differs at least by 3
- Maximum sum such that exactly half of the elements are selected and no two adjacent
- Maximum sum in circular array such that no two elements are adjacent | Set 2
- Convert a Binary Tree such that every node stores the sum of all nodes in its right subtree
- Generate Complete Binary Tree in such a way that sum of non-leaf nodes is minimum
- Remove nodes from Binary Tree such that sum of all remaining root-to-leaf paths is atleast K
- Maximum length cycle that can be formed by joining two nodes of a binary tree
- Minimum and maximum node that lies in the path connecting two nodes in a Binary Tree
- Maximum weighted edge in path between two nodes in an N-ary tree using binary lifting
- Count the nodes of the tree which make a pangram when concatenated with the sub-tree nodes
- Vertex Cover Problem | Set 2 (Dynamic Programming Solution for Tree)
- Minimum difference between any two weighted nodes in Sum Tree of the given Tree
- Check if max sum level of Binary tree divides tree into two equal sum halves
- Sum of nodes at maximum depth of a Binary Tree

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.