Skip to content
Related Articles
Largest subtree sum for each vertex of given N-ary Tree
• Difficulty Level : Medium
• Last Updated : 21 Jun, 2021

Given an N-array tree of N nodes, rooted at 1, with edges in the form {u, v}, and an array values[] consisting of N integers. Each vertex i has an integer value denoted by values[i]. The task is to find the largest Subtree Sum possible for each vertex i by adding its value to a non-empty subset of its child vertices.

Examples:

Input: Edges[][] = {{1, 2}, {1, 3}, {3, 4}}, values[] = {1, -1, 0, 1}
Output: 2 -1 1 1
Explanation:
Below is the given Tree:

1
/  \
2     3
\
4
Following subsets can be chosen for each vertex:
Vertex 1: Subset of vertices {1, 3, 4} can be chosen with values {1, 0, 1}. Therefore, sum = 1 + 0 + 1 = 2.
Vertex 2: Subset of vertices {2} can be chosen with values {-1}. Therefore, sum = -1.
Vertex 3: Subset of vertices {3, 4} can be chosen with values {0, 1}. Therefore, sum = 0 + 1 = 1.
Vertex 4: Subset of vertices {4} can be chosen with values {1}. Therefore, sum = 1.

Input: Edges[][] = {{1, 2}, {1, 3}, {2, 4}, {2, 5}}, values[] = {1, -1, -2, 1, 3}
Output: 5 4 -2 1 3
Explanation:
Below is the given Tree:

1
/  \
2     3
/   \
4      5
Following subsets can be chosen for each vertex:
Vertex 1: Subset of vertices {1, 4, 5} can be chosen with values {1, 1, 3}. Therefore, sum = 1 + 1 + 3 = 5.
Vertex 2: Subset of vertices {4, 5} can be chosen with values {1, 3}. Therefore, sum = 1 + 3 = 4.
Vertex 3: Subset of vertices {3} can be chosen with values {-2}. Therefore, sum = -2.
Vertex 4: Subset of vertices {4} can be chosen with values {1}. Therefore, sum = 1.
Vertex 5: Subset of vertices {5} can be chosen with values {3}. Therefore, sum = 3.

Naive Approach: The simplest approach is to traverse the subtree of each vertex i from 1 to N and perform DFS Traversal on it. For each vertex i, choose the subset of its child vertices having non-negative values. If the subset of chosen vertices is empty, then search and print the node having the minimum value such that it is the child node of vertex i. Otherwise, print the sum of node values of nodes present in the subset.

Time Complexity: O(N2)
Auxiliary Space: O(N)

Efficient Approach: The idea is to use DFS Traversal and Dynamic programming approach. Follow the below steps to solve the problem:

• Initialize an array ans[] of size N to store the maximum subtree sum for each vertex.
• Perform DFS Traversal for each vertex and for each vertex initialize v, ans[v] with some large negative value.
• If vertex v is a leaf vertex, then the answer for that vertex would be values[v]. Therefore, assign ans[v] = values[v].
• Otherwise, traverse the vertices adjacent to vertex v and for each adjacent vertex u, update ans[v] as ans[v] = max(ans[u] + values[v], values[v], ans[u]).
• After the above steps, print the values stored in ans[] array as the answer for each vertex.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach` `#include ` `using` `namespace` `std;` `#define V 3` `#define M 2`   `// Function to perform the DFS` `// Traversal on the given Tree` `void` `dfs(``int` `v, ``int` `p,` `         ``vector<``int``> adj[],` `     ``int` `ans[], ``int` `vals[])` `{` `    `  `    ``// To check if v is leaf vertex` `    ``bool` `isLeaf = 1;`   `    ``// Initialize answer for vertex v` `    ``ans[v] = INT_MIN;`   `    ``// Traverse adjacency list of v` `    ``for``(``int` `u : adj[v]) ` `    ``{` `        ``if` `(u == p)` `            ``continue``;` `            `  `        ``isLeaf = 0;` `        ``dfs(u, v, adj, ans, vals);`   `        ``// Update maximum subtree sum` `        ``ans[v] = max(ans[u] + vals[v],` `                 ``max(ans[u], vals[u]));` `    ``}`   `    ``// If v is leaf` `    ``if` `(isLeaf) ` `    ``{` `        ``ans[v] = vals[v];` `    ``}` `}`   `// Function to calculate maximum` `// subtree sum for each vertex` `void` `printAnswer(``int` `n, ` `                 ``int` `edges[V][M],` `                 ``int` `values[])` `{` `    `  `    ``// Stores the adjacency list` `    ``vector<``int``> adj[n];` `    `  `    ``// Add Edegs to the list` `    ``for``(``int` `i = 0; i < n - 1; i++) ` `    ``{` `        ``int` `u = edges[i] - 1;` `        ``int` `v = edges[i] - 1;` `        `  `        ``adj[u].push_back(v);` `        ``adj[v].push_back(u);` `    ``}`   `    ``// Stores largest subtree` `    ``// sum for each vertex` `    ``int` `ans[n] ;`   `    ``// Calculate answer` `    ``dfs(0, -1, adj, ans, values);`   `    ``// Print the result` `    ``for``(``auto` `x : ans) ` `    ``{` `        ``cout << x << ``" "``;` `    ``}` `}`   `// Driver Code` `int` `main()` `{` `    `  `    ``// Given nodes` `    ``int` `N = 4;`   `    ``// Give N edges` `    ``int` `edges[V][M] = { { 1, 2 },` `                        ``{ 1, 3 },` `                        ``{ 3, 4 } };`   `    ``// Given values` `    ``int` `values[] = { 1, -1, 0, 1 };`   `    ``// Function Call` `    ``printAnswer(N, edges, values);` `}`   `// This code is contributed by Princi Singh`

## Java

 `// Java program for the above approach`   `import` `java.io.*;` `import` `java.util.ArrayList;`   `@SuppressWarnings``(``"unchecked"``)` `class` `GFG {`   `    ``// Function to perform the DFS` `    ``// Traversal on the given Tree` `    ``static` `void` `dfs(``int` `v, ``int` `p,` `                    ``ArrayList adj[],` `                    ``int` `ans[], ``int` `vals[])` `    ``{`   `        ``// To check if v is leaf vertex` `        ``boolean` `isLeaf = ``true``;`   `        ``// Initialize answer for vertex v` `        ``ans[v] = Integer.MIN_VALUE;`   `        ``// Traverse adjacency list of v` `        ``for` `(``int` `u : adj[v]) {` `            ``if` `(u == p)` `                ``continue``;` `            ``isLeaf = ``false``;` `            ``dfs(u, v, adj, ans, vals);`   `            ``// Update maximum subtree sum` `            ``ans[v] = Math.max(` `                ``ans[u] + vals[v],` `                ``Math.max(ans[u],` `                         ``vals[u]));` `        ``}`   `        ``// If v is leaf` `        ``if` `(isLeaf) {` `            ``ans[v] = vals[v];` `        ``}` `    ``}`   `    ``// Function to calculate maximum` `    ``// subtree sum for each vertex` `    ``static` `void` `printAnswer(` `        ``int` `n, ``int` `edges[][], ``int` `values[])` `    ``{`   `        ``// Stores the adjacency list` `        ``ArrayList adj[]` `            ``= ``new` `ArrayList[n];`   `        ``for` `(``int` `i = ``0``; i < n; i++)` `            ``adj[i] = ``new` `ArrayList<>();`   `        ``// Add Edegs to the list` `        ``for` `(``int` `i = ``0``; i < n - ``1``; i++) {`   `            ``int` `u = edges[i][``0``] - ``1``;` `            ``int` `v = edges[i][``1``] - ``1``;` `            ``adj[u].add(v);` `            ``adj[v].add(u);` `        ``}`   `        ``// Stores largest subtree` `        ``// sum for each vertex` `        ``int` `ans[] = ``new` `int``[n];`   `        ``// Calculate answer` `        ``dfs(``0``, -``1``, adj, ans, values);`   `        ``// Print the result` `        ``for` `(``int` `x : ans) {` `            ``System.out.print(x + ``" "``);` `        ``}` `    ``}`   `    ``// Driver Code` `    ``public` `static` `void` `main(String[] args)` `    ``{` `        ``// Given nodes` `        ``int` `N = ``4``;`   `        ``// Give N edges` `        ``int` `edges[][]` `            ``= ``new` `int``[][] { { ``1``, ``2` `},` `                            ``{ ``1``, ``3` `},` `                            ``{ ``3``, ``4` `} };`   `        ``// Given values` `        ``int` `values[] = { ``1``, -``1``, ``0``, ``1` `};`   `        ``// Function Call` `        ``printAnswer(N, edges, values);` `    ``}` `}`

## Python3

 `# Python3 program for the above approach`   `V ``=` `3` `M ``=` `2`   `# Function to perform the DFS` `# Traversal on the given Tree` `def` `dfs(v, p):`   `    ``# To check if v is leaf vertex` `    ``isLeaf ``=` `1`   `    ``# Initialize answer for vertex v` `    ``ans[v] ``=` `-``10``*``*``9`   `    ``# Traverse adjacency list of v` `    ``for` `u ``in` `adj[v]:` `        ``if` `(u ``=``=` `p):` `            ``continue`   `        ``isLeaf ``=` `0` `        ``dfs(u, v)`   `        ``# Update maximum subtree sum` `        ``ans[v] ``=` `max``(ans[u] ``+` `vals[v],``max``(ans[u], vals[u]))`   `    ``# If v is leaf` `    ``if` `(isLeaf):` `        ``ans[v] ``=` `vals[v]`   `# Function to calculate maximum` `# subtree sum for each vertex` `def` `printAnswer(n, edges, vals):`   `    ``# Stores the adjacency list` `    ``# vector adj[n];`   `    ``# Add Edegs to the list` `    ``for` `i ``in` `range``(n ``-` `1``):` `        ``u ``=` `edges[i][``0``] ``-` `1` `        ``v ``=` `edges[i][``1``] ``-` `1`   `        ``adj[u].append(v)` `        ``adj[v].append(u)`   `    ``# Calculate answer` `    ``dfs(``0``, ``-``1``)`   `    ``# Prthe result` `    ``for` `x ``in` `ans:` `        ``print``(x, end``=``" "``)`   `# Driver Code` `if` `__name__ ``=``=` `'__main__'``:`   `    ``# Given nodes` `    ``N ``=` `4`   `    ``# Give N edges` `    ``edges``=``[ [ ``1``, ``2``],` `            ``[ ``1``, ``3``],` `            ``[ ``3``, ``4``] ]`   `    ``adj``=``[[] ``for` `i ``in` `range``(N)]` `    ``ans``=``[``0` `for` `i ``in` `range``(N)]`   `    ``# Given values` `    ``vals``=``[``1``, ``-``1``, ``0``, ``1``]`   `    ``# Function Call` `    ``printAnswer(N, edges, vals)`   `# This code is contributed by mohit kumar 29`

## C#

 `// C# program for the ` `// above approach` `using` `System;` `using` `System.Collections.Generic;` `class` `GFG{`   `// Function to perform the DFS` `// Traversal on the given Tree` `static` `void` `dfs(``int` `v, ``int` `p,` `                ``List<``int``> []adj,` `                ``int` `[]ans, ``int` `[]vals)` `{` `  ``// To check if v is leaf ` `  ``// vertex` `  ``bool` `isLeaf = ``true``;`   `  ``// Initialize answer for` `  ``// vertex v` `  ``ans[v] = ``int``.MinValue;`   `  ``// Traverse adjacency list` `  ``// of v` `  ``foreach` `(``int` `u ``in` `adj[v]) ` `  ``{` `    ``if` `(u == p)` `      ``continue``;` `    ``isLeaf = ``false``;` `    ``dfs(u, v, adj, ans, vals);`   `    ``// Update maximum subtree ` `    ``// sum` `    ``ans[v] = Math.Max(ans[u] +` `                      ``vals[v],` `             ``Math.Max(ans[u], ` `                      ``vals[u]));` `  ``}`   `  ``// If v is leaf` `  ``if` `(isLeaf)` `  ``{` `    ``ans[v] = vals[v];` `  ``}` `}`   `// Function to calculate maximum` `// subtree sum for each vertex` `static` `void` `printAnswer(``int` `n, ` `                        ``int` `[,]edges, ` `                        ``int` `[]values)` `{` `  ``// Stores the adjacency list` `  ``List<``int``> []adj = ` `       ``new` `List<``int``>[n];`   `  ``for` `(``int` `i = 0; i < n; i++)` `    ``adj[i] = ``new` `List<``int``>();`   `  ``// Add Edegs to the list` `  ``for` `(``int` `i = 0; ` `           ``i < n - 1; i++) ` `  ``{` `    ``int` `u = edges[i, 0] - 1;` `    ``int` `v = edges[i, 1] - 1;` `    ``adj[u].Add(v);` `    ``adj[v].Add(u);` `  ``}`   `  ``// Stores largest subtree` `  ``// sum for each vertex` `  ``int` `[]ans = ``new` `int``[n];`   `  ``// Calculate answer` `  ``dfs(0, -1, adj, ` `      ``ans, values);`   `  ``// Print the result` `  ``foreach` `(``int` `x ``in` `ans) ` `  ``{` `    ``Console.Write(x + ``" "``);` `  ``}` `}`   `// Driver Code` `public` `static` `void` `Main(String[] args)` `{` `  ``// Given nodes` `  ``int` `N = 4;`   `  ``// Give N edges` `  ``int` `[,]edges = ``new` `int``[,] {{1, 2},` `                             ``{1, 3},` `                             ``{3, 4}};` `  ``// Given values` `  ``int` `[]values = {1, -1, 0, 1};`   `  ``// Function Call` `  ``printAnswer(N, edges, values);` `}` `}`   `// This code is contributed by gauravrajput1`

## Javascript

 ``

Output:

`2 -1 1 1`

Time Complexity: O(N)
Auxiliary Space: O(N)

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.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with industry experts, please refer DSA Live Classes

My Personal Notes arrow_drop_up
Recommended Articles
Page :