Minimum cost such that path sum is at max K (Target Path Sum)
Last Updated :
06 Mar, 2024
Given a rooted tree consisting of N vertices. The vertices are numbered from 0 to N-1, and the root is the vertex 0. You are also given a value array Arr: Arr0, Arr1,….., Arrn-1. You can do any of these moves any number of times:
- Pick any node that is not root cut the edge between it and its parent and connect an edge between this node to the root. This move will cost 0 units.
- Pick any node U and change its value with the value of any other node. This move will cost A.
- Pick any node U and change its value with any non-negative integer. This move will cost B.
Find the minimum cost after which there is no path from the root to any node with a sum greater than K.
Note: Tree is given in form of parent array Par of size N where Par[I] denotes the parent of the ith node. In case ith node is root Par[i] = -1.
Examples:
Input: N=4, Par[] = {-1, 0, 1, 2}, Arr[] = {65, 2, 80, 4}, K = 8, A = 3, B = 1
Output: 2
Explanation: In one move we can pick node 3 and cut the edge between 2 and 3 and add an edge between 0 and 3, This will cost 0. Then we can pick node 0 and use third moves to update its value to 0. This will cost 1. And again we can pick node 2 and use third moves to update its value to 0. This will again cost 1. After this move, no subtree is left with sum > K. So the total cost will be 2.
Input: N = 2, Par[] = {-1, 0}, Arr[] = {36, 42}, K = 100, A = 30, B = 61
Output: 0
Explanation: There is no subtree with sum>k.
Illustration:
N=4, Par[] = {-1, 0, 1, 2}, Arr[] = {65, 2, 80, 4}, K = 8, A = 3, B = 1
0(65)
/
1(2)
/
2(80)
/
3(4)
Perform first step i.e. cut the edge from 2 and 3, append 3 to root(0). This will cost 0.
0(65)
/ \
(2)1 3(4)
/
2(80)
Now root itself having greater value than k i.e 65>8, change the value of root to 0, costing B(1). Total cost = 1.
0(0)
/ \
(2)1 3(4)
/
2(80)
Now right part is having value less than k. But left part is still exceeding k. Therefore changed 2(80) to 2(0) at a cost B. Total cost = 2
0(0)
/ \
(2)1 3(4)
/
2(0)
Hence, 2 is the minimum cost.
Approach: To solve the problem, follow the below idea:
The problem can be solved by exploring all the cases. It is clear that we should connect all the nodes directly to the root as it would minimize the path sum and the cost will also be 0. Now, we can get the minimum cost by solving for the below cases:
- Case 1: Do not change the value of the root and replace all those node’s value whose path sum becomes greater than K(Arr[0] + Arr[node] > K) with the minimum value among all nodes. The total cost will be A * number of nodes whose values are changed.
- Case 2: Do not change the value of the root and replace all those node’s value whose path sum becomes greater than K(Arr[0] + Arr[node] > K) with 0. The total cost will be B * number of nodes whose values are changed.
- Case 3: Replace the value of the root with minimum value among all nodes and replace all those node’s value whose path sum becomes greater than K(Arr[0] + Arr[node] > K) with the minimum value among all nodes. The total cost will be A + A * number of nodes whose values are changed.
- Case 4: Replace the value of the root with 0 and replace all those node’s value whose path sum becomes greater than K(Arr[0] + Arr[node] > K) with 0. The total cost will be B + min(A, B) * number of nodes whose values are changed.
We can return the minimum of the four cases to get the final answer.
Step-by-step algorithm:
- Maintain a function helper(rootVal, nodeVal, cost) which returns the minimum cost to make the path sum at max K, where rootVal is the value of the root node, nodeVal is the updated value of the other nodes and cost is the cost for updating the value of a node.
- Call helper() for all the above cases to get the most optimal answer.
Below is the implementation of the approach:
C++
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll INF = 1e18;
ll helper( int rootval, int nodeVal, int cost, int K,
vector< int >& arr)
{
ll res = 0;
int n = arr.size();
for ( int i = 1; i < n; i++) {
if (rootval + arr[i] <= K)
continue ;
else if (rootval + nodeVal <= K)
res += cost;
else
return INF;
}
return res;
}
long long solve( int n, vector< int >& Par, vector< int >& arr,
int K, int A, int B)
{
int minv = *min_element(arr.begin(), arr.end());
ll res = helper(arr[0], minv, A, K, arr);
res = min(res, helper(arr[0], 0, B, K, arr));
res = min(res, A + helper(minv, minv, A, K, arr));
res = min(res, B + helper(0, 0, min(A, B), K, arr));
return res == INF ? -1 : res;
}
int main()
{
int N = 4;
vector< int > Par = { -1, 0, 1, 2 };
vector< int > Arr = { 65, 2, 80, 4 };
int K = 8;
int A = 3;
int B = 1;
cout << solve(N, Par, Arr, K, A, B);
return 0;
}
|
Java
import java.util.Collections;
import java.util.List;
class GFG {
static final long INF = ( long )(1e18);
static long helper( int rootval, int nodeVal, int cost,
int K, List<Integer> arr)
{
long res = 0 ;
int n = arr.size();
for ( int i = 1 ; i < n; i++) {
if (rootval + arr.get(i) <= K)
continue ;
else if (rootval + nodeVal <= K)
res += cost;
else
return INF;
}
return res;
}
static long solve( int n, List<Integer> Par,
List<Integer> arr, int K, int A,
int B)
{
int minv = Collections.min(arr);
long res = helper(arr.get( 0 ), minv, A, K, arr);
res = Math.min(res,
helper(arr.get( 0 ), 0 , B, K, arr));
res = Math.min(res,
A + helper(minv, minv, A, K, arr));
res = Math.min(
res, B + helper( 0 , 0 , Math.min(A, B), K, arr));
return res == INF ? - 1 : res;
}
public static void main(String[] args)
{
int N = 4 ;
List<Integer> Par = List.of(- 1 , 0 , 1 , 2 );
List<Integer> Arr = List.of( 65 , 2 , 80 , 4 );
int K = 8 ;
int A = 3 ;
int B = 1 ;
System.out.println(solve(N, Par, Arr, K, A, B));
}
}
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
static long INF = ( long )1e18;
static long Helper( int rootVal, int nodeVal, int cost, int K, List< int > arr)
{
long res = 0;
int n = arr.Count;
for ( int i = 1; i < n; i++)
{
if (rootVal + arr[i] <= K)
continue ;
else if (rootVal + nodeVal <= K)
res += cost;
else
return INF;
}
return res;
}
static long Solve( int n, List< int > Par, List< int > arr, int K, int A, int B)
{
int minv = arr.Min();
long res = Helper(arr[0], minv, A, K, arr);
res = Math.Min(res, Helper(arr[0], 0, B, K, arr));
res = Math.Min(res, A + Helper(minv, minv, A, K, arr));
res = Math.Min(res, B + Helper(0, 0, Math.Min(A, B), K, arr));
return res == INF ? -1 : res;
}
public static void Main()
{
int N = 4;
List< int > Par = new List< int > { -1, 0, 1, 2 };
List< int > Arr = new List< int > { 65, 2, 80, 4 };
int K = 8;
int A = 3;
int B = 1;
Console.WriteLine(Solve(N, Par, Arr, K, A, B));
}
}
|
Javascript
function helper(rootVal, nodeVal, cost, K, arr) {
let res = 0;
const n = arr.length;
for (let i = 1; i < n; i++) {
if (rootVal + arr[i] <= K) continue ;
else if (rootVal + nodeVal <= K) res += cost;
else return Infinity;
}
return res;
}
function solve(n, Par, arr, K, A, B) {
const minv = Math.min(...arr);
let res = helper(arr[0], minv, A, K, arr);
res = Math.min(res, helper(arr[0], 0, B, K, arr));
res = Math.min(res, A + helper(minv, minv, A, K, arr));
res = Math.min(res, B + helper(0, 0, Math.min(A, B), K, arr));
return res === Infinity ? -1 : res;
}
const N = 4;
const Par = [-1, 0, 1, 2];
const Arr = [65, 2, 80, 4];
const K = 8;
const A = 3;
const B = 1;
console.log(solve(N, Par, Arr, K, A, B));
|
Python3
def helper(rootval, nodeVal, cost, K, arr):
res = 0
n = len (arr)
for i in range ( 1 , n):
if rootval + arr[i] < = K:
continue
elif rootval + nodeVal < = K:
res + = cost
else :
return float ( 'inf' )
return res
def solve(n, Par, arr, K, A, B):
minv = min (arr)
res = helper(arr[ 0 ], minv, A, K, arr)
res = min (res, helper(arr[ 0 ], 0 , B, K, arr))
res = min (res, A + helper(minv, minv, A, K, arr))
res = min (res, B + helper( 0 , 0 , min (A, B), K, arr))
return res if res ! = float ( 'inf' ) else - 1
if __name__ = = "__main__" :
N = 4
Par = [ - 1 , 0 , 1 , 2 ]
Arr = [ 65 , 2 , 80 , 4 ]
K = 8
A = 3
B = 1
print (solve(N, Par, Arr, K, A, B))
|
Time Complexity: O(N), where N is the number of vertices in the graph.
Auxiliary Space: O(1)
Share your thoughts in the comments
Please Login to comment...