Maximum cost of splitting given Binary Tree into two halves

Given a Binary Tree with N nodes valued 0 to N – 1 and N-1 edges and an array arr[] consisting of values of edges, the task is to find the maximum cost of splitting the tree into two halves. 
 

The cost of splitting a tree is equal to the product of sum of node values of the splitted subtrees.

Examples:

Input: N = 6, arr[] = {13, 8, 7, 4, 5, 9}, Edges[][] = {{0, 1}, {1, 2}, {1, 4}, {3, 4}, {4, 5}}
Output: 504
Explanation:
Below is the given tree and resultant tree after removing the edge:



Remove the edge between 1st and 4th, then
t1 = valueat[0] + valueat[1] + valueat[2] = 13 + 8 + 7
t1 = valueat[3] + valueat[4] + valueat[5] = 4 + 5 + 9
t1*t2 = (13 + 8 + 7) * (4 + 5 + 9) = 504

Input: N = 7, arr[]= {13, 8, 7, 4, 5, 9, 100}, Edges[][] = { {0, 1}, {1, 2}, {1, 4}, {3, 4}, {4, 5}, {2, 6}}
Output: 4600
Explanation:
Below is the given tree and resultant tree after removing the edge:

Remove the edge between 2nd and 6th, then
t1 = valueat[0] + valueat[1] + valueat[2] + valueat[3] + valueat[4] + valueat[5]= 13 + 8 + 7 + 4 + 5 + 9
t2 = valueat[6] = 100
t1*t2 = (13 + 8 + 7 + 5 + 4 + 9) * (100) = 4600

Approach: The idea is to traverse the given tree and try to break the tree at every possible edge and then find the maximum cost of splitting at that edges. After all the above steps print the maximum cost among all the splitting. Below are the steps:

  1. All the edges are stored using the adjacency list edges and values at each node is stored in the given array arr[].
  2. For the current-node, find the sum of values in its descendants including itself.
  3. Suppose if the edge between the current node and its parent is removed then two trees can be formed.
  4. Now, calculate values of t1, t2, and check the product of t1 and t2 is maximum or not.
  5. Repeat this process recursively to all the child-nodes of current-node.

Below is the implementation of the above approach:

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// To store the results and sum of
// all nodes in the array
int ans = 0, allsum = 0;
 
// To create adjacency list
vector<int> edges[100001];
 
// Function to add edges into the
// adjacency list
void addedge(int a, int b)
{
    edges[a].push_back(b);
    edges[b].push_back(a);
}
 
// Recursive function that calculate
// the value of the cost of splitting
// the tree recursively
void findCost(int r, int p, int arr[])
{
    int i, cur;
 
    for (i = 0; i < edges[r].size();
         i++) {
 
        // Fetch the child of node-r
        cur = edges[r].at(i);
 
        // Neglect if cur node is parent
        if (cur == p)
            continue;
 
        findCost(cur, r, arr);
 
        // Add all values of nodes
        // which are decendents of r
        arr[r] += arr[cur];
    }
 
    // The two trees formed are rooted
    // at 'r' with its decendents
    int t1 = arr[r];
    int t2 = allsum - t1;
 
    // Check and replace if current
    // product t1*t2 is large
    if (t1 * t2 > ans) {
        ans = t1 * t2;
    }
}
 
// Function to find the maximum cost
// after splitting the tree in 2 halves
void maximumCost(int r, int p,
                 int N, int M,
                 int arr[],
                 int Edges[][2])
{
    // Find sum of values in all nodes
    for (int i = 0; i < N; i++) {
        allsum += arr[i];
    }
 
    // Traverse edges to create
    // adjacency list
    for (int i = 0; i < M; i++) {
        addedge(Edges[i][0],
                Edges[i][1]);
    }
 
    // Function Call
    findCost(r, p, arr);
}
 
// Driver Code
int main()
{
    int a, b, N = 6;
 
    // Values in each node
    int arr[] = { 13, 8, 7, 4, 5, 9 };
 
    int M = 5;
 
    // Given Edges
    int Edges[][2] = { { 0, 1 }, { 1, 2 },
                       { 1, 4 }, { 3, 4 },
                       { 4, 5 } };
 
    maximumCost(1, -1, N, M, arr, Edges);
 
    cout << ans;
    return 0;
}
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program for the above approach
import java.util.*;
class GFG{
  
// To store the results and sum of
// all nodes in the array
static int ans = 0, allsum = 0;
  
// To create adjacency list
static Vector<Integer> []edges = new Vector[100001];
  
// Function to add edges into the
// adjacency list
static void addedge(int a, int b)
{
    edges[a].add(b);
    edges[b].add(a);
}
  
// Recursive function that calculate
// the value of the cost of splitting
// the tree recursively
static void findCost(int r, int p, int arr[])
{
    int i, cur;
    for (i = 0; i < edges[r].size(); i++)
    {
        // Fetch the child of node-r
        cur = edges[r].get(i);
  
        // Neglect if cur node is parent
        if (cur == p)
            continue;
  
        findCost(cur, r, arr);
  
        // Add all values of nodes
        // which are decendents of r
        arr[r] += arr[cur];
    }
  
    // The two trees formed are rooted
    // at 'r' with its decendents
    int t1 = arr[r];
    int t2 = allsum - t1;
  
    // Check and replace if current
    // product t1*t2 is large
    if (t1 * t2 > ans)
    {
        ans = t1 * t2;
    }
}
  
// Function to find the maximum cost
// after splitting the tree in 2 halves
static void maximumCost(int r, int p,
                        int N, int M,
                        int arr[],
                        int Edges[][])
{
    // Find sum of values in all nodes
    for (int i = 0; i < N; i++)
    {
        allsum += arr[i];
    }
  
    // Traverse edges to create
    // adjacency list
    for (int i = 0; i < M; i++)
    {
        addedge(Edges[i][0],
                Edges[i][1]);
    }
  
    // Function Call
    findCost(r, p, arr);
}
  
// Driver Code
public static void main(String[] args)
{
    int a, b, N = 6;
  
    // Values in each node
    int arr[] = {13, 8, 7, 4, 5, 9};
  
    int M = 5;
  
    // Given Edges
    int Edges[][] = {{0, 1}, {1, 2},
                     {1, 4}, {3, 4},
                     {4, 5}};
    for (int i = 0; i < edges.length; i++)
        edges[i] = new Vector<Integer>();
    maximumCost(1, -1, N, M, arr, Edges);
    System.out.print(ans);
}
}
  
// This code is contributed by Amit Katiyar
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG{
  
// To store the results and sum of
// all nodes in the array
static int ans = 0, allsum = 0;
  
// To create adjacency list
static List<int> []edges = new List<int>[100001];
  
// Function to add edges into the
// adjacency list
static void addedge(int a, int b)
{
    edges[a].Add(b);
    edges[b].Add(a);
}
  
// Recursive function that calculate
// the value of the cost of splitting
// the tree recursively
static void findCost(int r, int p, int []arr)
{
    int i, cur;
    for (i = 0; i < edges[r].Count; i++)
    {
        // Fetch the child of node-r
        cur = edges[r][i];
  
        // Neglect if cur node is parent
        if (cur == p)
            continue;
  
        findCost(cur, r, arr);
  
        // Add all values of nodes
        // which are decendents of r
        arr[r] += arr[cur];
    }
  
    // The two trees formed are rooted
    // at 'r' with its decendents
    int t1 = arr[r];
    int t2 = allsum - t1;
  
    // Check and replace if current
    // product t1*t2 is large
    if (t1 * t2 > ans)
    {
        ans = t1 * t2;
    }
}
  
// Function to find the maximum cost
// after splitting the tree in 2 halves
static void maximumCost(int r, int p,
                        int N, int M,
                        int []arr, int [, ]Edges)
{
    // Find sum of values in all nodes
    for (int i = 0; i < N; i++)
    {
        allsum += arr[i];
    }
  
    // Traverse edges to create
    // adjacency list
    for (int i = 0; i < M; i++)
    {
        addedge(Edges[i, 0],
                Edges[i, 1]);
    }
  
    // Function Call
    findCost(r, p, arr);
}
  
// Driver Code
public static void Main(String[] args)
{
    int  N = 6;
  
    // Values in each node
    int []arr = {13, 8, 7, 4, 5, 9};
  
    int M = 5;
  
    // Given Edges
    int [,]Edges = {{0, 1},
                    {1, 2}, {1, 4},
                    {3, 4}, {4, 5}};
    for (int i = 0; i < edges.Length; i++)
        edges[i] = new List<int>();
    maximumCost(1, -1, N, M, arr, Edges);
    Console.Write(ans);
}
}
  
// This code is contributed by Rajput-Ji
chevron_right

Output: 
504





 

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.





Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : amit143katiyar, Rajput-Ji

Article Tags :
Practice Tags :