Open In App

Maximum Path sum in a N-ary Tree

Last Updated : 02 Dec, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Given an undirected tree with n nodes numbered from 1 to n and an array arr[] where arr[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: arr[] = [4, -1, -3, 5, 7, -2],  edges[][] = [[1, 2], [1, 3], [2, 4], [2, 5], [2, 6]]
Output: 11
Explanation: The maximum path sum will between node 4 and 5 through node 2. i.e., 5 - 1 + 7 = 11

Maximum-Path-sum-in-a-N-ary-Tree-1


Input: arr[] = [2, 3, 4], edges[][] = [[1, 2], [1, 3]]
Output: 9
Explanation: The maximum path sum will between all the nodes i.e., 2 + 3 + 4 = 9

Maximum-Path-sum-in-a-N-ary-Tree-2

Approach:

The idea is to calculate the maximum path sum for each node by finding the two longest paths starting from that node and reaching its descendants. The maximum path sum for a node is the sum of its value and the two largest path sums from its children. The algorithm uses depth-first search to explore all nodes, avoiding cycles by keeping track of the parent node. The maximum path sum is updated whenever a larger sum is found.

C++
// C++ code to find maximum path sum
// in a N-ary tree.
#include <bits/stdc++.h>
using namespace std;

int maxSumRecur(int node, int prev, 
                vector<vector<int>> &adj, vector<int> &arr, int &ans) {
    int maxi1 = 0, maxi2 = 0;

    // Traverse all child nodes of the current node
    for (auto v : adj[node]) {

        // Skip the parent node to avoid cycles
        if (v != prev) {
            int val = maxSumRecur(v, node, adj, arr, ans);
            if (val > maxi1) {
                maxi2 = maxi1;
                maxi1 = val;
            }
            else if (val > maxi2) {
                maxi2 = val;
            }
        }
    }

    // Update the answer with the best path sum
    ans = max(ans, arr[node - 1] + maxi1 + maxi2);

    // Return the maximum path sum starting
    // at this node, considering its subtree
    return arr[node - 1] + maxi1;
}

int maxSum(vector<vector<int>> &edges, vector<int> &arr) {
    int n = arr.size();
    vector<vector<int>> adj(n + 1);

    for (auto edge : edges) {
        adj[edge[0]].push_back(edge[1]);
        adj[edge[1]].push_back(edge[0]);
    }

    int ans = 0;
    maxSumRecur(1, -1, adj, arr, ans);
    return ans;
}

int main() {
  
    vector<int> arr = {4, -1, -3, 5, 7, -2};
    vector<vector<int>> edges = {{1, 2}, {1, 3}, {2, 4}, {2, 5}, {2, 6}};
    cout << maxSum(edges, arr);
    return 0;
}
Java
// Java code to find maximum path sum
// in a N-ary tree.
import java.util.*;

class GfG {

    static int
    maxSumRecur(int node, int prev,
                ArrayList<ArrayList<Integer> > adj, int[] arr,
                int[] ans) {
        int maxi1 = 0, maxi2 = 0;

        // Traverse all child nodes of the current node
        for (int v : adj.get(node)) {

            // Skip the parent node to avoid cycles
            if (v != prev) {
                int val = maxSumRecur(v, node, adj, arr, ans);
                if (val > maxi1) {
                    maxi2 = maxi1;
                    maxi1 = val;
                }
                else if (val > maxi2) {
                    maxi2 = val;
                }
            }
        }

        // Update the answer with the best path sum
        ans[0]
            = Math.max(ans[0], arr[node - 1] + maxi1 + maxi2);

        // Return the maximum path sum starting
        // at this node, considering its subtree
        return arr[node - 1] + maxi1;
    }

    static int maxSum(int[][] edges, int[] arr) {
        int n = arr.length;
        ArrayList<ArrayList<Integer> > adj
            = new ArrayList<>(n + 1);

        // Create adjacency list
        for (int i = 0; i <= n; i++) {
            adj.add(new ArrayList<>());
        }

        for (int[] edge : edges) {
            adj.get(edge[0]).add(edge[1]);
            adj.get(edge[1]).add(edge[0]);
        }

        int[] ans = { 0 };
        maxSumRecur(1, -1, adj, arr, ans);
        return ans[0];
    }

    public static void main(String[] args) {
      
        int[] arr = { 4, -1, -3, 5, 7, -2 };
        int[][] edges = {
            { 1, 2 }, { 1, 3 }, { 2, 4 }, { 2, 5 }, { 2, 6 }
        };

        System.out.println(maxSum(edges, arr));
    }
}
Python
# Python code to find maximum path sum
# in a N-ary tree.
def maxSumRecur(node, prev, adj, arr, ans):
    maxi1 = 0
    maxi2 = 0

    # Traverse all child nodes of the current node
    for v in adj[node]:

        # Skip the parent node to avoid cycles
        if v != prev:
            val = maxSumRecur(v, node, adj, arr, ans)
            if val > maxi1:
                maxi2 = maxi1
                maxi1 = val
            elif val > maxi2:
                maxi2 = val

    # Update the answer with the best path sum
    ans[0] = max(ans[0], arr[node - 1] + maxi1 + maxi2)

    # Return the maximum path sum starting
    # at this node, considering its subtree
    return arr[node - 1] + maxi1


def maxSum(edges, arr):
    n = len(arr)
    adj = [[] for _ in range(n + 1)]

    # Create adjacency list
    for edge in edges:
        adj[edge[0]].append(edge[1])
        adj[edge[1]].append(edge[0])

    ans = [0]
    maxSumRecur(1, -1, adj, arr, ans)
    return ans[0]


if __name__ == "__main__":
    arr = [4, -1, -3, 5, 7, -2]
    edges = [
        [1, 2], [1, 3], [2, 4], [2, 5], [2, 6]
    ]

    print(maxSum(edges, arr))
C#
// C# program to find Maximum 
// Path sum in a N-ary Tree
using System;
using System.Collections.Generic;

class GfG {
    
    static int maxSumRecur(int node, int prev, 
    List<List<int>> adj, int[] arr, ref int ans) {
        int maxi1 = 0, maxi2 = 0;

        // Traverse all child nodes of the current node
        foreach (int v in adj[node]) {
            
            // Skip the parent node to avoid cycles
            if (v != prev) {
                int val = maxSumRecur(v, node, adj, arr, ref ans);
                if (val > maxi1) {
                    maxi2 = maxi1;
                    maxi1 = val;
                }
                else if (val > maxi2) {
                    maxi2 = val;
                }
            }
        }

        // Update the answer with the best path sum
        ans = Math.Max(ans, arr[node - 1] + maxi1 + maxi2);

        // Return the maximum path sum starting 
        // at this node, considering its subtree
        return arr[node - 1] + maxi1;
    }

    static int maxSum(int[,] edges, int[] arr) {
        int n = arr.Length;
        List<List<int>> adj = new List<List<int>>(new List<int>[n + 1]);

        // Create adjacency list
        for (int i = 0; i <= n; i++) {
            adj[i] = new List<int>();
        }

        for (int i = 0; i < edges.GetLength(0); i++) {
            adj[edges[i, 0]].Add(edges[i, 1]);
            adj[edges[i, 1]].Add(edges[i, 0]);
        }

        int ans = 0;
        maxSumRecur(1, -1, adj, arr, ref ans);
        return ans;
    }

    static void Main(string[] args) {
        int[] arr = { 4, -1, -3, 5, 7, -2 };
        int[,] edges = {
            { 1, 2 }, { 1, 3 }, { 2, 4 }, { 2, 5 }, { 2, 6 }
        };

        Console.WriteLine(maxSum(edges, arr));
    }
}
JavaScript
// JavaScript program to find
// Maximum Path sum in a N-ary Tree

function maxSumRecur(node, prev, adj, arr, ans) {

    let maxi1 = 0, maxi2 = 0;

    // Traverse all child nodes of the current node
    for (let v of adj[node]) {

        // Skip the parent node to avoid cycles
        if (v !== prev) {
            let val = maxSumRecur(v, node, adj, arr, ans);
            if (val > maxi1) {
                maxi2 = maxi1;
                maxi1 = val;
            }
            else if (val > maxi2) {
                maxi2 = val;
            }
        }
    }

    // Update the answer with the best path sum
    ans[0] = Math.max(ans[0], arr[node - 1] + maxi1 + maxi2);

    // Return the maximum path sum starting
    // at this node, considering its subtree
    return arr[node - 1] + maxi1;
}

function maxSum(edges, arr) {

    let n = arr.length;
    let adj = Array.from({length : n + 1}, () => []);

    // Create adjacency list
    for (let edge of edges) {
        adj[edge[0]].push(edge[1]);
        adj[edge[1]].push(edge[0]);
    }

    let ans = [ 0 ];
    maxSumRecur(1, -1, adj, arr, ans);
    return ans[0];
}

let arr = [ 4, -1, -3, 5, 7, -2 ];
let edges =
    [ [ 1, 2 ], [ 1, 3 ], [ 2, 4 ], [ 2, 5 ], [ 2, 6 ] ];

console.log(maxSum(edges, arr));

Output
11

Time Complexity: O(n) , where n is the number of nodes in the tree.
Auxiliary Space: O(n)


Next Article
Article Tags :
Practice Tags :

Similar Reads