Open In App

Minimum moves to make tree nodes non-negative

Last Updated : 09 Mar, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a tree consisting of N nodes where the value of each node is the negative of its node number (i.e., 1st node has a value of -1, 2nd node has a value of -2, and so on) and a parent array Par[] that stores the parent node of the ith node. You can choose any node from the tree and add 1 to all nodes in the path from the root of the tree to that particular node. The task is to find the minimum number of operations to make all the values of the tree non-negative.

Note: The parent array uses 1-based indexing. The root of the tree is node 1 and thus its parent is marked as -1 in the parent array. 

Examples:

Input: N = 5, Par[] = {-1, 1, 2, 2, 4}
Output: 8
Explanation: Choose 3 as node three times and 5 as node five times. The following tree can be constructed using a parent array. -1 is treated as root.
          1 
        /
     2
  /   \
3    4
        \
        5

Input: N = 3, Par[] = {-1, 3, 1}
Output:  3
Explanation: Choose 2 as node three times. Given tree looks like
    1
    |
   3
   |
  2

Approach: Implement the idea below to solve the problem

To make ith node non-negative, we have to increment at least i times. So the optimal way is to increment the values of a path such that the increment operation does not exceed the maximum value along the path.

Follow the below steps to implement the idea:

  • Create an adjacency list adj[] to store the tree in it.
  • Now use DFS to traverse the tree and for every node consider the maximum of the node value and the sum of the results of the child nodes as the minimum operations for that node.
  • In the end, the root node will get the result for the complete tree. 

Below is the implementation of the above approach:

C++




// C++ implementation of the code
#include <bits/stdc++.h>
using namespace std;
 
// Function to iterate over each node and
// find the max from node value and its child
// node
long long dfs(long long node, vector<vector<int> >& adj)
{
 
    // Assigning node value to ans
    long long ans = node;
 
    // Store the sum of child nodes
    long long sum = 0;
 
    for (auto child : adj[node])
        sum += dfs(child, adj);
 
    // Update the ans
    ans = max(ans, sum);
 
    return ans;
}
 
// Function to find minimum sum required
// to make tree non-negative
long long solve(int n, vector<int>& P)
{
 
    // Creating adjacency List
    vector<vector<int> > adj(n + 1);
 
    for (int i = 0; i < n; i++) {
        if (P[i] == -1)
            continue;
        adj[P[i]].push_back(i + 1);
    }
 
    // Starting traversal from parent node 1
    return dfs(1, adj);
}
 
// Driver Code
int main()
{
    int N = 5;
    vector<int> Par = { -1, 1, 2, 2, 4 };
 
    // Function call
    cout << solve(N, Par) << endl;
 
    return 0;
}


Java




// Java implementation of the code
 
import java.io.*;
import java.util.*;
 
class GFG {
 
    // Function to iterate over each node and
    // find the max from node value and its child
    // node
    static int dfs(int node, List<List<Integer> > adj)
    {
 
        // Assigning node value to ans
        int ans = node;
 
        // Store the sum of child nodes
        int sum = 0;
 
        List<Integer> temp = adj.get(node);
        for (var child : temp) {
            sum += dfs(child, adj);
        }
 
        // Update the ans
        ans = Math.max(ans, sum);
 
        return ans;
    }
 
    // Function to find minimum sum required
    // to make tree non-negative
    static int solve(int n, int[] P)
    {
 
        // Creating adjacency List
        List<List<Integer> > adj = new ArrayList<>();
        for (int i = 0; i <= n; i++) {
            adj.add(new ArrayList<Integer>());
        }
 
        for (int i = 0; i < n; i++) {
            if (P[i] == -1) {
                continue;
            }
            adj.get(P[i]).add(i + 1);
        }
 
        // Starting traversal from parent node 1
        return dfs(1, adj);
    }
 
    public static void main(String[] args)
    {
        int N = 5;
        int[] Par = { -1, 1, 2, 2, 4 };
 
        // Function call
        System.out.println(solve(N, Par));
    }
}
 
// This code is contributed by lokesh


Python3




# Python implementation of the code
 
# Function to iterate over each node and
# find the max from node value and its child
# node
def dfs(node, adj):
 
    # Assigning node value to ans
    ans = node
 
    # Store the sum of child nodes
    sum = 0
 
    for child in adj[node]:
        sum += dfs(child, adj)
 
    # Update the ans
    ans = max(ans, sum)
 
    return ans
 
# Function to find minimum sum required
# to make tree non-negative
def solve(n, P):
 
    # Creating adjacency List
    adj = [list() for _ in range(n + 1)]
 
    for i in range(n):
        if P[i] == -1:
            continue
        adj[P[i]].append(i + 1)
 
    # Starting traversal from parent node 1
    return dfs(1, adj)
 
 
# Driver Code
if __name__ == '__main__':
    N = 5
    Par = [-1, 1, 2, 2, 4]
 
    # Function call
    print(solve(N, Par))
     
# This code is contributed by ksam24000


C#




// C# implementation of the code
using System;
using System.Collections.Generic;
 
public class GFG {
 
    // Function to iterate over each node and
    // find the max from node value and its child
    // node
    static int dfs(int node, List<List<int> > adj)
    {
        // Assigning node value to ans
        int ans = node;
 
        // Store the sum of child nodes
        int sum = 0;
 
        List<int> temp = adj[node];
        foreach(var child in temp)
        {
            sum += dfs(child, adj);
        }
 
        // Update the ans
        ans = Math.Max(ans, sum);
 
        return ans;
    }
 
    // Function to find minimum sum required
    // to make tree non-negative
    static int solve(int n, int[] P)
    {
        // Creating adjacency List
        List<List<int> > adj = new List<List<int> >();
        for (int i = 0; i <= n; i++) {
            adj.Add(new List<int>());
        }
 
        for (int i = 0; i < n; i++) {
            if (P[i] == -1) {
                continue;
            }
            adj[P[i]].Add(i + 1);
        }
 
        // Starting traversal from parent node 1
        return dfs(1, adj);
    }
 
    static public void Main()
    {
 
        // Code
        int N = 5;
        int[] Par = { -1, 1, 2, 2, 4 };
 
        // Function call
        Console.WriteLine(solve(N, Par));
    }
}
 
// This code is contributed by lokeshmvs21.


Javascript




// Javascript implementation of the code
 
// Function to iterate over each node and
// find the max from node value and its child
// node
function dfs(node, adj){
 
    // Assigning node value to ans
    let ans = node;
 
    // Store the sum of child nodes
    let sum = 0;
     
    for(let child=0;child<adj[node].length;child++)
    {
        sum += dfs(adj[node][child], adj);
    }
 
    // Update the ans
    ans = Math.max(ans, sum);
 
    return ans;
}
// Function to find minimum sum required
// to make tree non-negative
function solve(n, P){
 
    // Creating adjacency List
    let adj = [];
    for(let i=0;i<n+1;i++)
    {
        adj.push([]);
    }
 
    for (let i = 0; i < n; i++){
        if (P[i] == -1){
            continue;
        }
        adj[P[i]].push(i + 1);
    }
 
    // Starting traversal from parent node 1
    return dfs(1, adj);
}
 
let N = 5;
let Par = [-1, 1, 2, 2, 4];
 
// Function call
console.log(solve(N, Par));
     
// This code is contributed by Pushpesh Raj.


Output

8

Time Complexity: O(V+E) where V is the number of nodes in the tree and E is the number of edges
Auxiliary Space: O(V) where V is the number of nodes in the tree

Related Articles:



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads