Skip to content
Related Articles

Related Articles

Improve Article
Save Article
Like Article

Maximum sum possible for every node by including it in a segment of N-Ary Tree

  • Difficulty Level : Hard
  • Last Updated : 28 Sep, 2021

Given an N-Ary tree containing N nodes and an array weight [ ] that denotes the weight of the nodes which can be positive or negative, the task for every node is to print the maximum sum possible by a sequence of nodes including the current node.

Examples:

Input: N = 7
weight[] = [-8, 9, 7, -4, 5, -10, -6]
N-Ary tree:
                -8
               /   \
              9      7
            /  \    / 
          -4    5 -10
          /
        -6
Output: 13 14 13 10 14 3 4

Explanations:
Node -8: [-8 + 9 + 7 + 5] = 13
Node 9: [9 + 5] = 14
Node 3: [7 + (-8) + 9 + 5] = 13
Node 4: [-4 + 9 + 5] = 10
Node: [5 + 9] = 14
Node 6: [-10 + 7 + (-8) + 9 + 5] = 3
Node 7: [-6 + (-4) + 9 + 5] = 4

Input: N = 6
weight[] = [2, -7, -5, 8, 4, -10]
N-Ary tree:
                 2
               /   \
             -7    -5
             / \     \
            8   4    -10
Output: 7 7 2 8 7 -8

Approach: This problem can be solved using Dp on Trees technique by applying two DFS.

  • Apply the first DFS to store the maximum sum possible for every node by including them in a sequence with their respective successors. Store the maximum possible sum in dp1[]. array.
  • Maximum possible value for each node in the first DFS can be obtained by:

dp1[node] += maximum(0, dp1[child1], dp1[child2], …)
 

  • Perform the second Dfs to update the maximum sum for each node in dp1[] by including them in a sequence with their ancestors also. The maximum values stored in dp2[] for every node are the required answers.
  • Maximum possible value for each node in the second DFS can be obtained by:

dp2[node] = dp1[node] + maximum(0, maxSumAncestors)
Best answer can be obtained by including or excluding the maximum sum possible for its ancestors
where maxSumAncestors = dp2[parent] – maximum(0, dp1[node]), i.e. including or excluding contribution of the maximum sum of the current node stored in dp1[]
 

Refer to the pictorial explanation for better understanding:

Below is the implementation of the above approach:

C++




// C++ program to calculate the maximum
// sum possible for every node by including
// it in a segment of the N-Ary Tree
#include <bits/stdc++.h>
using namespace std;
 
// Stores the maximum
// sum possible for every node
// by including them in a segment
// with their successors
int dp1[100005];
 
// Stores the maximum
// sum possible for every node
// by including them in a segment
// with their ancestors
int dp2[100005];
 
// Store the maximum sum
// for every node by
// including it in a
// segment with its successors
void dfs1(int u, int par,
          vector<int> g[],
          int weight[])
{
 
    dp1[u] = weight[u];
    for (auto c: g[u]) {
        if (c != par) {
            dfs1(c, u, g, weight);
            dp1[u] += max(0, dp1);
        }
    }
}
 
// Update the maximum sums
// for each node by including
// them in a sequence with
// their ancestors
void dfs2(int u, int par,
          vector<int> g[],
          int weight[])
{
    // Condition to check,
    // if current node is not root
    if (par != 0) {
        int maxSumAncestors = dp2[par]
                              - max(0, dp1[u]);
        dp2[u] = dp1[u] + max(0,
                              maxSumAncestors);
    }
    for (auto c: g[u]) {
        if (c != par) {
            dfs2(c, u, g, weight);
        }
    }
}
 
// Add edges
void addEdge(int u, int v, vector<int> g[])
{
    g[u].push_back(v);
    g[v].push_back(u);
}
 
// Function to find the maximum
// answer for each node
void maxSumSegments(vector<int> g[],
                    int weight[],
                    int n)
{
 
    // Compute the maximum sums
    // with successors
    dfs1(1, 0, g, weight);
 
    // Store the computed maximums
    for (int i = 1; i <= n; i++) {
        dp2[i] = dp1[i];
    }
 
    // Update the maximum sums
    // by including their
    // ancestors
    dfs2(1, 0, g, weight);
}
 
// Print the desired result
void printAns(int n)
{
    for (int i = 1; i <= n; i++) {
        cout << dp2[i] << " ";
    }
}
 
// Driver Program
int main()
{
 
    // Number of nodes
    int n = 6;
    int u, v;
 
    // graph
    vector<int> g[100005];
 
    // Add edges
    addEdge(1, 2, g);
    addEdge(1, 3, g);
    addEdge(2, 4, g);
    addEdge(2, 5, g);
    addEdge(3, 6, g);
    addEdge(4, 7, g);
 
    // Weight of each node
    int weight[n + 1];
    weight[1] = -8;
    weight[2] = 9;
    weight[3] = 7;
    weight[4] = -4;
    weight[5] = 5;
    weight[6] = -10;
    weight[7] = -6;
 
    // Compute the max sum
    // of segments for each
    // node
    maxSumSegments(g, weight, n);
 
    // Print the answer
    // for every node
    printAns(n);
 
    return 0;
}

Java




// Java program to calculate the maximum
// sum possible for every node by including
// it in a segment of the N-Ary Tree
import java.util.*;
public class Main
{
    // Stores the maximum
    // sum possible for every node
    // by including them in a segment
    // with their successors
    static int[] dp1 = new int[100005];
       
    // Stores the maximum
    // sum possible for every node
    // by including them in a segment
    // with their ancestors
    static int[] dp2 = new int[100005];
      
    // Store the maximum sum for every
    // node by including it in a
    // segment with its successors
    static void dfs1(int u, int par,
                     Vector<Vector<Integer>> g,
                     int[] weight)
    {
        dp1[u] = weight[u];
   
        for(int c = 0; c < g.get(u).size(); c++)
        {
            if (g.get(u).get(c) != par)
            {
                dfs1(g.get(u).get(c), u, g, weight);
                dp1[u] += Math.max(0, dp1[g.get(u).get(c)]);
            }
        }
    }
   
    // Update the maximum sums
    // for each node by including
    // them in a sequence with
    // their ancestors
    static void dfs2(int u, int par,
                     Vector<Vector<Integer>> g,
                     int[] weight)
    {
       
        // Condition to check,
        // if current node is not root
        if (par != 0)
        {
            int maxSumAncestors = dp2[par] - Math.max(0, dp1[u]);
            dp2[u] = dp1[u] + Math.max(0, maxSumAncestors);
        }
   
        for(int c = 0; c < g.get(u).size(); c++)
        {
            if (g.get(u).get(c) != par)
            {
                dfs2(g.get(u).get(c), u, g, weight);
            }
        }
    }
   
    // Add edges
    static void addEdge(int u, int v, Vector<Vector<Integer>> g)
    {
        g.get(u).add(v);
        g.get(v).add(u);
    }
   
    // Function to find the maximum
    // answer for each node
    static void maxSumSegments(Vector<Vector<Integer>> g, int[] weight, int n)
    {
        
        // Compute the maximum sums
        // with successors
        dfs1(1, 0, g, weight);
   
        // Store the computed maximums
        for(int i = 1; i < n + 1; i++)
            dp2[i] = dp1[i];
   
        // Update the maximum sums
        // by including their
        // ancestors
        dfs2(1, 0, g, weight);
    }
   
    // Print the desired result
    static void printAns(int n)
    {
        for(int i = 1; i < n; i++)
            System.out.print(dp2[i] + " ");
    }
     
    public static void main(String[] args)
    {
       
        // Number of nodes
        int n = 7;
         
        // Graph
        Vector<Vector<Integer>> g = new Vector<Vector<Integer>>();
        for(int i = 0; i < 100005; i++)
        {
            g.add(new Vector<Integer>());
        }
         
        // Add edges
        addEdge(1, 2, g);
        addEdge(1, 3, g);
        addEdge(2, 4, g);
        addEdge(2, 5, g);
        addEdge(3, 6, g);
        addEdge(4, 7, g);
         
        // Weight of each node
        int[] weight = new int[n + 1];
        weight[1] = -8;
        weight[2] = 9;
        weight[3] = 7;
        weight[4] = -4;
        weight[5] = 5;
        weight[6] = -10;
        weight[7] = -6;
         
        // Compute the max sum
        // of segments for each
        // node
        maxSumSegments(g, weight, n);
         
        // Print the answer
        // for every node
        printAns(n);
    }
}
 
// This code is contributed by divyeshrabadiya07.

Python3




# Python3 program to calculate the maximum
# sum possible for every node by including
# it in a segment of the N-Ary Tree
  
# Stores the maximum
# sum possible for every node
# by including them in a segment
# with their successors
dp1 = [0 for i in range(100005)]
  
# Stores the maximum sum possible
# for every node by including them
# in a segment with their ancestors
dp2 = [0 for i in range(100005)]
  
# Store the maximum sum for every
# node by including it in a
# segment with its successors
def dfs1(u, par, g, weight):
  
    dp1[u] = weight[u]
     
    for c in g[u]:
        if (c != par):
            dfs1(c, u, g, weight)
            dp1[u] += max(0, dp1)
         
# Update the maximum sums
# for each node by including
# them in a sequence with
# their ancestors
def dfs2(u, par, g, weight):
 
    # Condition to check,
    # if current node is not root
    if (par != 0):
        maxSumAncestors = dp2[par] - max(0, dp1[u])
        dp2[u] = dp1[u] + max(0, maxSumAncestors)
     
    for c in g[u]:
        if (c != par):
            dfs2(c, u, g, weight)
             
# Add edges
def addEdge(u, v, g):
 
    g[u].append(v)
    g[v].append(u)
 
# Function to find the maximum
# answer for each node
def maxSumSegments(g, weight, n):
  
    # Compute the maximum sums
    # with successors
    dfs1(1, 0, g, weight)
  
    # Store the computed maximums
    for i in range(1, n + 1):
        dp2[i] = dp1[i]
     
    # Update the maximum sums
    # by including their
    # ancestors
    dfs2(1, 0, g, weight)
 
# Print the desired result
def printAns(n):
 
    for i in range(1, n):
        print(dp2[i], end = ' ')
         
# Driver code
if __name__=='__main__':
     
    # Number of nodes
    n = 7
    u = 0
    v = 0
  
    # Graph
    g = [[] for i in range(100005)]
  
    # Add edges
    addEdge(1, 2, g)
    addEdge(1, 3, g)
    addEdge(2, 4, g)
    addEdge(2, 5, g)
    addEdge(3, 6, g)
    addEdge(4, 7, g)
  
    # Weight of each node
    weight=[0 for i in range(n + 1)]
    weight[1] = -8
    weight[2] = 9
    weight[3] = 7
    weight[4] = -4
    weight[5] = 5
    weight[6] = -10
    weight[7] = -6
  
    # Compute the max sum
    # of segments for each
    # node
    maxSumSegments(g, weight, n)
  
    # Print the answer
    # for every node
    printAns(n)
 
# This code is contributed by pratham76

C#




// C# program to calculate the maximum
// sum possible for every node by including
// it in a segment of the N-Ary Tree
using System;
using System.Collections.Generic;
class GFG {
     
    // Stores the maximum
    // sum possible for every node
    // by including them in a segment
    // with their successors
    static int[] dp1 = new int[100005];
      
    // Stores the maximum
    // sum possible for every node
    // by including them in a segment
    // with their ancestors
    static int[] dp2 = new int[100005];
     
    // Store the maximum sum for every
    // node by including it in a
    // segment with its successors
    static void dfs1(int u, int par, List<List<int>> g, int[] weight)
    {
        dp1[u] = weight[u];
  
        for(int c = 0; c < g[u].Count; c++)
        {
            if (g[u] != par)
            {
                dfs1(g[u], u, g, weight);
                dp1[u] += Math.Max(0, dp1[g[u]]);
            }
        }
    }
  
    // Update the maximum sums
    // for each node by including
    // them in a sequence with
    // their ancestors
    static void dfs2(int u, int par, List<List<int>> g, int[] weight)
    {
        // Condition to check,
        // if current node is not root
        if (par != 0)
        {
            int maxSumAncestors = dp2[par] - Math.Max(0, dp1[u]);
            dp2[u] = dp1[u] + Math.Max(0, maxSumAncestors);
        }
  
        for(int c = 0; c < g[u].Count; c++)
        {
            if (g[u] != par)
            {
                dfs2(g[u], u, g, weight);
            }
        }
    }
  
    // Add edges
    static void addEdge(int u, int v, List<List<int>> g)
    {
        g[u].Add(v);
        g[v].Add(u);
    }
  
    // Function to find the maximum
    // answer for each node
    static void maxSumSegments(List<List<int>> g, int[] weight, int n)
    {
       
        // Compute the maximum sums
        // with successors
        dfs1(1, 0, g, weight);
  
        // Store the computed maximums
        for(int i = 1; i < n + 1; i++)
            dp2[i] = dp1[i];
  
        // Update the maximum sums
        // by including their
        // ancestors
        dfs2(1, 0, g, weight);
    }
  
    // Print the desired result
    static void printAns(int n)
    {
        for(int i = 1; i < n; i++)
            Console.Write(dp2[i] + " ");
    }
 
  static void Main() {
    // Number of nodes
    int n = 7;
    
    // Graph
    List<List<int>> g = new List<List<int>>();
    for(int i = 0; i < 100005; i++)
    {
        g.Add(new List<int>());
    }
    
    // Add edges
    addEdge(1, 2, g);
    addEdge(1, 3, g);
    addEdge(2, 4, g);
    addEdge(2, 5, g);
    addEdge(3, 6, g);
    addEdge(4, 7, g);
    
    // Weight of each node
    int[] weight = new int[n + 1];
    weight[1] = -8;
    weight[2] = 9;
    weight[3] = 7;
    weight[4] = -4;
    weight[5] = 5;
    weight[6] = -10;
    weight[7] = -6;
    
    // Compute the max sum
    // of segments for each
    // node
    maxSumSegments(g, weight, n);
    
    // Print the answer
    // for every node
    printAns(n);
  }
}
 
// This code is contributed by divyesh072019.

Javascript




<script>
    // Javascript program to calculate the maximum
    // sum possible for every node by including
    // it in a segment of the N-Ary Tree
     
    // Stores the maximum
    // sum possible for every node
    // by including them in a segment
    // with their successors
    let dp1 = [];
 
    // Stores the maximum
    // sum possible for every node
    // by including them in a segment
    // with their ancestors
    let dp2 = [];
     
    for(let i = 0; i < 100005; i++)
    {
        dp1.push(0);
        dp2.push(0);
    }
     
    // Store the maximum sum for every
    // node by including it in a
    // segment with its successors
    function dfs1(u, par, g, weight)
    {
        dp1[u] = weight[u];
 
        for(let c = 0; c < g[u].length; c++)
        {
            if (g[u] != par)
            {
                dfs1(g[u], u, g, weight);
                dp1[u] += Math.max(0, dp1[g[u]]);
            }
        }
    }
 
    // Update the maximum sums
    // for each node by including
    // them in a sequence with
    // their ancestors
    function dfs2(u, par, g, weight)
    {
        // Condition to check,
        // if current node is not root
        if (par != 0)
        {
            maxSumAncestors = dp2[par] - Math.max(0, dp1[u]);
            dp2[u] = dp1[u] + Math.max(0, maxSumAncestors);
        }
 
        for(let c = 0; c < g[u].length; c++)
        {
            if (g[u] != par)
            {
                dfs2(g[u], u, g, weight);
            }
        }
    }
 
    // Add edges
    function addEdge(u, v, g)
    {
        g[u].push(v);
        g[v].push(u);
    }
 
    // Function to find the maximum
    // answer for each node
    function maxSumSegments(g, weight, n)
    {
        // Compute the maximum sums
        // with successors
        dfs1(1, 0, g, weight);
 
        // Store the computed maximums
        for(let i = 1; i < n + 1; i++)
            dp2[i] = dp1[i];
 
        // Update the maximum sums
        // by including their
        // ancestors
        dfs2(1, 0, g, weight);
    }
 
    // Print the desired result
    function printAns(n)
    {
        for(let i = 1; i < n; i++)
            document.write(dp2[i] + " ");
    }
     
    // Number of nodes
    let n = 7, u = 0, v = 0;
   
    // Graph
    let g = [];
    for(let i = 0; i < 100005; i++)
    {
        g.push([]);
    }
   
    // Add edges
    addEdge(1, 2, g);
    addEdge(1, 3, g);
    addEdge(2, 4, g);
    addEdge(2, 5, g);
    addEdge(3, 6, g);
    addEdge(4, 7, g);
   
    // Weight of each node
    let weight = new Array(n + 1);
    weight.fill(0);
    weight[1] = -8;
    weight[2] = 9;
    weight[3] = 7;
    weight[4] = -4;
    weight[5] = 5;
    weight[6] = -10;
    weight[7] = -6;
   
    // Compute the max sum
    // of segments for each
    // node
    maxSumSegments(g, weight, n);
   
    // Print the answer
    // for every node
    printAns(n);
 
// This code is contributed by suresh07.
</script>
Output:
13 14 13 10 14 3

 


My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!