Minimum moves to make tree nodes non-negative
Last Updated :
09 Mar, 2023
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++
#include <bits/stdc++.h>
using namespace std;
long long dfs( long long node, vector<vector< int > >& adj)
{
long long ans = node;
long long sum = 0;
for ( auto child : adj[node])
sum += dfs(child, adj);
ans = max(ans, sum);
return ans;
}
long long solve( int n, vector< int >& P)
{
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);
}
return dfs(1, adj);
}
int main()
{
int N = 5;
vector< int > Par = { -1, 1, 2, 2, 4 };
cout << solve(N, Par) << endl;
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static int dfs( int node, List<List<Integer> > adj)
{
int ans = node;
int sum = 0 ;
List<Integer> temp = adj.get(node);
for (var child : temp) {
sum += dfs(child, adj);
}
ans = Math.max(ans, sum);
return ans;
}
static int solve( int n, int [] P)
{
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 );
}
return dfs( 1 , adj);
}
public static void main(String[] args)
{
int N = 5 ;
int [] Par = { - 1 , 1 , 2 , 2 , 4 };
System.out.println(solve(N, Par));
}
}
|
Python3
def dfs(node, adj):
ans = node
sum = 0
for child in adj[node]:
sum + = dfs(child, adj)
ans = max (ans, sum )
return ans
def solve(n, P):
adj = [ list () for _ in range (n + 1 )]
for i in range (n):
if P[i] = = - 1 :
continue
adj[P[i]].append(i + 1 )
return dfs( 1 , adj)
if __name__ = = '__main__' :
N = 5
Par = [ - 1 , 1 , 2 , 2 , 4 ]
print (solve(N, Par))
|
C#
using System;
using System.Collections.Generic;
public class GFG {
static int dfs( int node, List<List< int > > adj)
{
int ans = node;
int sum = 0;
List< int > temp = adj[node];
foreach ( var child in temp)
{
sum += dfs(child, adj);
}
ans = Math.Max(ans, sum);
return ans;
}
static int solve( int n, int [] P)
{
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);
}
return dfs(1, adj);
}
static public void Main()
{
int N = 5;
int [] Par = { -1, 1, 2, 2, 4 };
Console.WriteLine(solve(N, Par));
}
}
|
Javascript
function dfs(node, adj){
let ans = node;
let sum = 0;
for (let child=0;child<adj[node].length;child++)
{
sum += dfs(adj[node][child], adj);
}
ans = Math.max(ans, sum);
return ans;
}
function solve(n, P){
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);
}
return dfs(1, adj);
}
let N = 5;
let Par = [-1, 1, 2, 2, 4];
console.log(solve(N, Par));
|
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:
Share your thoughts in the comments
Please Login to comment...