Open In App

Maximum Path sum in a N-ary Tree

Last Updated : 26 Dec, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Given an undirected tree with N nodes numbered from 1 to N and an array A[] where A[i] denotes the value assigned to (i+1)th node.  The connections between the nodes are provided in a 2-dimensional array edges[]. The task is to find the maximum path sum between any two nodes. (Both the nodes can be the same also).

Note: The path sum is equal to the sum of the value of the nodes of that path.

Examples:

Input: N = 6, A[] = {4, -1, -3, 5, 7, -2},  
edges[][] = {{1, 2}, {1, 3}, {2, 4}, {2, 5}, {2, 6}}
Output: 11     
Explanation: The Simple path sum between node 4 and 5 through node 2. i.e., 5-1+7 = 11

maximum path sum = 11

maximum path sum = 11

Input: N = 3, A[] = {2, 3, 4}, edges[][] = {{1, 2}, {1, 3}}
Output: 9

Naive Approach: A simple solution is to find the path sum between every two nodes by depth first search in the tree and then find the maximum of them.

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

Efficient Approach: An efficient approach to solve the problem in one depth first search traversal is based on the following idea: 

The idea is that, for each node, find two paths(the paths starting from that node and reaching to any depth) with the maximum path sum. The maximum result for that node will be equal to the sum of those two paths with the node.
The maximum among all the nodes is the maximum path sum of the tree.

Follow the steps to solve the problem:

  • Use a DFS traversal starting from the root.
  • Use an array to store the maximum path sum starting from a node.
  • In each DFS traversal:
    • Find the two maximum path sums of starting from that (say maximumBranchSum1 and maximumBranchSum2) which stores 0 if the maximum path sum is negative (because the starting and ending node of a path can be same as mentioned in the problem).
    • Store the maximum path sum in the array
    • The maximum path sum of the path passing through the current node and belonging to its subtree is the sum of the two maximum paths and A[i]
  • The maximum value among all such maximum path sums is the required answer.

Below is the implementation for the above approach:

C++




// C++ code to implement the approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Final result variable
int result = 0;
 
// Helper function to calculate
// the maximum path sum using DFS
void findMaximumPathSum(int currentNode,
                        int previousNode,
                        vector<int> adj[],
                        int A[])
{
    // Nodes to which currentNode is
    // connected to
    vector<int> v = adj[currentNode];
    int maximumBranchSum1 = 0;
    int maximumBranchSum2 = 0;
    for (int i = 0; i < v.size(); i++) {
 
        // checking whether the branch is
        // visited already
        if (v[i] == previousNode) {
            continue;
        }
        findMaximumPathSum(v[i], currentNode,
                           adj, A);
 
        // Storing the maximum of value of
        // branch path sums
        // maximumBranchSum1 will store the
        // maximum value
        // maximumBranchSum2 will store the
        // 2nd most maximum value
        if (A[v[i]] > maximumBranchSum1) {
            maximumBranchSum2 = maximumBranchSum1;
            maximumBranchSum1 = A[v[i]];
        }
        else {
            maximumBranchSum2
                = max(maximumBranchSum2, A[v[i]]);
        }
    }
    result = max(result,
                 A[currentNode] + maximumBranchSum1
                     + maximumBranchSum2);
 
    // updating the value of current value
    // with maximum path sum including
    // currentNode
    A[currentNode] += maximumBranchSum1;
}
 
// Function to get the maximum path sum
void print(int A[], int N, pair<int, int> edges[])
{
    vector<int> adj[N];
 
    // adjacency list for undirected graph
    for (int i = 0; i < N - 1; i++) {
        int x = edges[i].first;
        int y = edges[i].second;
        adj[x - 1].push_back(y - 1);
        adj[y - 1].push_back(x - 1);
    }
    findMaximumPathSum(0, -1, adj, A);
    cout << result << endl;
}
 
// Driver code
int main()
{
    int N = 6;
    int A[N] = { 4, -1, -3, 5, 7, -2 };
    pair<int, int> edges[N - 1] = {
        { 1, 2 }, { 1, 3 }, { 2, 4 }, { 2, 5 }, { 2, 6 }
    };
 
    // Function call
    print(A, N, edges);
    return 0;
}


Java




// Java code to implement the approach
 
import java.io.*;
import java.util.*;
 
class GFG {
 
    // Function to add edge
    static void addEdge(ArrayList<ArrayList<Integer> > adj,
                        int s, int d)
    {
        adj.get(s).add(d);
        adj.get(d).add(s);
    }
    static int result = 0;
 
    // Helper function to calculate
    // the maximum path sum using DFS
    public static void
    findMaximumPathSum(int currentNode,
                       int previousNode,
                       ArrayList<ArrayList<Integer> > adj,
                       int A[])
    {
 
        // Nodes to which currentNode
        // is connected to
        ArrayList<Integer> v = adj.get(currentNode);
        int maximumBranchSum1 = 0, maximumBranchSum2 = 0;
        for (int i = 0; i < v.size(); i++) {
 
            // Checking whether the branch
            // is visited already
            if (v.get(i) == previousNode) {
                continue;
            }
            findMaximumPathSum(v.get(i),
                               currentNode, adj,
                               A);
 
            // Storing the maximum of value of branch path
            // sums maximumBranchSum1 will store the maximum
            // value maximumBranchSum2 will store the 2nd
            // most maximum value
            if (A[v.get(i)] > maximumBranchSum1) {
                maximumBranchSum2
                    = maximumBranchSum1;
                maximumBranchSum1
                    = A[v.get(i)];
            }
            else {
                maximumBranchSum2 = Math.max(
                    maximumBranchSum2, A[v.get(i)]);
            }
        }
        result = Math.max(result, A[currentNode]
                                      + maximumBranchSum1
                                      + maximumBranchSum2);
 
        // Updating the value of current node with
        // maximum path sum including currentNode
        A[currentNode] += maximumBranchSum1;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int N = 6;
        int A[] = { 4, -1, -3, 5, 7, -2 };
        ArrayList<ArrayList<Integer> > adj
            = new ArrayList<ArrayList<Integer> >(N);
 
        for (int i = 0; i < N; i++)
            adj.add(new ArrayList<Integer>());
 
        addEdge(adj, 0, 1);
        addEdge(adj, 0, 2);
        addEdge(adj, 1, 3);
        addEdge(adj, 1, 4);
        addEdge(adj, 1, 5);
 
        // Driver code
        findMaximumPathSum(0, -1, adj, A);
        System.out.println(result);
    }
}


Python3




# Python code to implement the approach
 
# Function to add edge
def addEdge(adj, s, d):
    adj[s].append(d)
    adj[d].append(s)
 
result = 0
 
# Helper function to calculate
# the maximum path sum using DFS
def findMaximumPathSum(currentNode, previousNode, adj, A):
 
    # Nodes to which currentNode
    # is connected to
    v = adj[currentNode]
    maximumBranchSum1 = 0
    maximumBranchSum2 = 0
    for i in range(len(v)):
 
        # Checking whether the branch
        # is visited already
        if (v[i] == previousNode):
            continue
 
        findMaximumPathSum(v[i],
                           currentNode, adj,
                           A)
 
        # Storing the maximum of value of branch path
        # sums maximumBranchSum1 will store the maximum
        # value maximumBranchSum2 will store the 2nd
        # most maximum value
        if (A[v[i]] > maximumBranchSum1):
            maximumBranchSum2 = maximumBranchSum1
            maximumBranchSum1 = A[v[i]]
 
        else:
            maximumBranchSum2 = max(maximumBranchSum2, A[v[i]])
 
    global result
    result = max(result, A[currentNode] +
                 maximumBranchSum1 + maximumBranchSum2)
 
    # Updating the value of current node with
    # maximum path sum including currentNode
    A[currentNode] += maximumBranchSum1
 
 
# Driver code
 
N = 6
A = [4, -1, -3, 5, 7, -2]
adj = []
 
for i in range(N):
    adj.append([])
 
addEdge(adj, 0, 1)
addEdge(adj, 0, 2)
addEdge(adj, 1, 3)
addEdge(adj, 1, 4)
addEdge(adj, 1, 5)
 
# Driver code
findMaximumPathSum(0, -1, adj, A)
print(result)
 
# This code is contributed by gfgking.


C#




// C# code for the above approach
using System;
using System.Collections.Generic;
 
namespace MaximumPathSumInTree
{
  class Program
  {
    static void Main(string[] args)
    {
      int N = 6;
      int[] A = { 4, -1, -3, 5, 7, -2 };
      List<List<int>> adj = new List<List<int>>(N);
 
      for (int i = 0; i < N; i++)
        adj.Add(new List<int>());
 
      AddEdge(adj, 0, 1);
      AddEdge(adj, 0, 2);
      AddEdge(adj, 1, 3);
      AddEdge(adj, 1, 4);
      AddEdge(adj, 1, 5);
 
      // Driver code
      FindMaximumPathSum(0, -1, adj, A);
      Console.WriteLine(result);
    }
 
    // Function to add edge
    static void AddEdge(List<List<int>> adj, int s, int d)
    {
      adj[s].Add(d);
      adj[d].Add(s);
    }
 
    static int result = 0;
 
    // Helper function to calculate
    // the maximum path sum using DFS
    public static void
      FindMaximumPathSum(int currentNode,
                         int previousNode,
                         List<List<int>> adj,
                         int[] A)
    {
 
      // Nodes to which currentNode
      // is connected to
      List<int> v = adj[currentNode];
      int maximumBranchSum1 = 0, maximumBranchSum2 = 0;
      for (int i = 0; i < v.Count; i++)
      {
        // Checking whether the branch
        // is visited already
        if (v[i] == previousNode)
        {
          continue;
        }
        FindMaximumPathSum(v[i],
                           currentNode, adj,
                           A);
 
        // Storing the maximum of value of branch path
        // sums maximumBranchSum1 will store the maximum
        // value maximumBranchSum2 will store the 2nd
        // most maximum value
        if (A[v[i]] > maximumBranchSum1)
        {
          maximumBranchSum2
            = maximumBranchSum1;
          maximumBranchSum1
            = A[v[i]];
        }
        else
        {
          maximumBranchSum2 = Math.Max(
            maximumBranchSum2, A[v[i]]);
        }
      }
      result = Math.Max(result, A[currentNode]
                        + maximumBranchSum1
                        + maximumBranchSum2);
 
      // Updating the value of current node with
      // maximum path sum including currentNode
      A[currentNode] += maximumBranchSum1;
    }
  }
}
 
// This code is contributed by Potta Lokesh


Javascript




<script>
// Javascript code to implement the approach
 
 
// Function to add edge
function addEdge(adj, s, d) {
    adj[s].push(d);
    adj[d].push(s);
}
let result = 0;
 
// Helper function to calculate
// the maximum path sum using DFS
function findMaximumPathSum(currentNode, previousNode, adj, A) {
 
    // Nodes to which currentNode
    // is connected to
    let v = adj[currentNode];
    let maximumBranchSum1 = 0, maximumBranchSum2 = 0;
    for (let i = 0; i < v.length; i++) {
 
        // Checking whether the branch
        // is visited already
        if (v[i] == previousNode) {
            continue;
        }
        findMaximumPathSum(v[i],
            currentNode, adj,
            A);
 
        // Storing the maximum of value of branch path
        // sums maximumBranchSum1 will store the maximum
        // value maximumBranchSum2 will store the 2nd
        // most maximum value
        if (A[v[i]] > maximumBranchSum1) {
            maximumBranchSum2
                = maximumBranchSum1;
            maximumBranchSum1
                = A[v[i]];
        }
        else {
            maximumBranchSum2 = Math.max(
                maximumBranchSum2, A[v[i]]);
        }
    }
    result = Math.max(result, A[currentNode]
        + maximumBranchSum1
        + maximumBranchSum2);
 
    // Updating the value of current node with
    // maximum path sum including currentNode
    A[currentNode] += maximumBranchSum1;
}
 
// Driver code
 
let N = 6;
let A = [4, -1, -3, 5, 7, -2];
let adj = [];
 
for (let i = 0; i < N; i++)
    adj.push([]);
 
addEdge(adj, 0, 1);
addEdge(adj, 0, 2);
addEdge(adj, 1, 3);
addEdge(adj, 1, 4);
addEdge(adj, 1, 5);
 
// Driver code
findMaximumPathSum(0, -1, adj, A);
document.write(result);
 
// This code is contributed by Saurabh Jaiswal
</script>


Output

11

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



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads