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++ program for the above approach #include <bits/stdc++.h> 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 Edges 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].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 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<Integer> 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<Integer> adj[]
= new ArrayList[n];
for ( int i = 0 ; i < n; i++)
adj[i] = new ArrayList<>();
// Add Edges 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 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<int> adj[n];
# Add Edges 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 )
# Print the 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# 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 Edges 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 |
<script> // JavaScript program for the above approach
// Function to perform the DFS
// Traversal on the given Tree
function dfs(v, p, adj, ans, vals)
{
// To check if v is leaf
// vertex
let isLeaf = true ;
// Initialize answer for
// vertex v
ans[v] = Number.MIN_VALUE;
// Traverse adjacency list
// of v
for (let u = 0; u < adj[v].length; u++)
{
if (adj[v][u] == p)
continue ;
isLeaf = false ;
dfs(adj[v][u], v, adj, ans, vals);
// Update maximum subtree
// sum
ans[v] = Math.max(ans[adj[v][u]] +
vals[v],
Math.max(ans[adj[v][u]],
vals[adj[v][u]]));
}
// If v is leaf
if (isLeaf)
{
ans[v] = vals[v];
}
}
// Function to calculate maximum
// subtree sum for each vertex
function printAnswer(n, edges, values)
{
// Stores the adjacency list
let adj = new Array(n);
for (let i = 0; i < n; i++)
adj[i] = [];
// Add Edges to the list
for (let i = 0; i < n - 1; i++)
{
let u = edges[i][0] - 1;
let v = edges[i][1] - 1;
adj[u].push(v);
adj[v].push(u);
}
// Stores largest subtree
// sum for each vertex
let ans = new Array(n);
// Calculate answer
dfs(0, -1, adj, ans, values);
// Print the result
for (let x = 0; x < ans.length; x++)
{
document.write(ans[x] + " " );
}
}
// Given nodes
let N = 4;
// Give N edges
let edges = [[1, 2], [1, 3], [3, 4]];
// Given values
let values = [1, -1, 0, 1];
// Function Call
printAnswer(N, edges, values);
</script> |
2 -1 1 1
Time Complexity: O(N)
Auxiliary Space: O(N)