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
\
5Input: 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++ 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 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 |
# 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# 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 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. |
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: