You are given a tree with nodes, numbered from 1 to n. Each node has an integer value .
You can perform at most k operations. In one operation, you may pick a leaf node and reattach it to any node.
After all operations, define Xi as the sum of values in the subtree rooted at node i . Your goal is to minimize sum of All Xi.









did this question come in any OA?
Yupp ...google
I was thinking of solving it using DP.For each node, I keep a dp[u][k], which means the maximum gain we can get from the subtree of u if we do exactly k operations inside it. It's like a knapsack: each child subtree gives us some set of gains based on how many moves we spend on it,and we want to combine them to get the best possible total using at most K moves. O(n*k*(work on each state))= o(n*k*(nk*k))
Gain : let's say u have a leaf at depth d when u reattach it to root overall score will decrease by (d-1)*node_val We can precompute this using dfs in o(n)
If some one has better approsch PLZZ SHARE
As far as I know, that is the most optimal solution, since the problem is equivalent to knapsack problem. TC should be O(n*k*k) if we do transitions directly.
Oo!!..can u share the transitions..or do u I think I am evaluating time complexity of my code incorrectly?
dp[v][i] = max(dp[v][i],dp[v][j]+dp[u][k]) where j+k = i, v is a parent of u. Base is dp[v][sz(v)] = benefit if we delete the whole subtree, other values are 0.
Why u are considering it a binary tree?
is this what you want to say?
I am updating dp[v] by iterating over its children one by one.
Basically you are distributing each i from 0,k
between node and the child. But this is not working
It should be working. Here is my full solution:
do you remember the constraints of the problem?? Thought about it for 10-15 mins, first fell trap to greedy. I have also come to a solution resembling yours! Knapsack DP on subtree sums
Did you solve it during the Online Asssessment?
N <= 1e3, k <= 1e2 and Ai <= 1e5
oh then it is solvable using simple knapsack DP, n * k^2. Thanks!
try to minimize the contribution of each node to the final answer
and contribution will be depth*a[i] or (depth+1)*a[i] according to your depth definiton
so remove the leaf with max value of depth*a[i] and put it to node ..
repeat the operation k times..
It wouldn't work since the set of leaves may change. For example, in the optimal answer we may use operation on a vertex and on its parent after that.
ohh yes greedy will be wrong.. then i think dp solution is good..
Depth matters because a node’s value contributes to the subtree sums of all its ancestors so more the depth more it adds to the total.That’s why just looking at a node’s value isn’t enough; we must also consider its depth. Greedy fails because sometimes a high-gain move is only possible after clearing its children first.So even if a leaf seems a bad choice now, moving it night unlock a much better move later.thats's why I dp can solve this.
I think greedy works ,just with some modifications like keeping track of when does a new leaf node gets formed, as said now just pick the next best one . It did passed according to my friend
Are the values at the nodes all positive ? And what about the constraints ?
Well it was asked by my friend so I don't knwo constraints on n or k, but yes values are positive. I am just looking for a better solution.
Quite Nice Problem ! Here is my solution O(N*K) EULER TOUR + KNAPSACK
It is obvious that the contribution of a particular node is (depth[i] + 1) * val[i] (Considering depth of root to be 0)
Now some observations : ->For every node if at all we choose to apply operation then most optimal will be to connect that node directly to the root [Since that way contribution becomes 2 * val[i] and that's the min possible] ->If we apply the operation on a node then have to apply on every node in its subtree
So compute the gain (depth[i] — 1) * val[i] for all nodes And then sum all the gains from a subtree on the subtree's root also compute the subtree sizes
Let that array formed be arr Now perform EULER TOUR on the tree and let that array be 'e' (All subtree nodes follow their root node) now make the array a where a[i] = arr[e[i]]
Now apply knapsack on a and dp[i][k] = max(dp[i+1][k], a[i] + dp[i+ss[i]][k-ss[i]) ss[i] = subtree size of 'i'
I guess it should be dp[i][k] = max(dp[i+1][k], a[i] + dp[i+ss[i]][k-ss[i]]).
Yeah corrected it .
I had the exact same idea.
But when applying knapsack, we may select some nodes in our optimal answer which may be ancestors of other. Won't that be a problem then as we may include some subtrees twice?
No that's where the euler tour comes into play. Look at the dp transition. When not taking a node we explore the subtree nodes. But when taking, we skip exactly ss[i] nodes thereby skipping its entire subtree. So no double counting is there. Study the euler tour to get better idea on it.
we can solve this using just tree traversal in nk^2 dp but using euler tour we can solve it in nk thats why you think of this approach right ?
Thanks for your explanation. I get it now.
Previously, I was trying to relate dp[i] and dp[i-1], so that looked a bit hard. But when we try to reverse the array or write dp forward, it becomes clean.
Do you remember the other problems ?
This solution would work I think. Used priority queue and then selected the top k contributors leaving beside the root and connected them to the root so that their contribution minimizes. contribution is just depth[node]*value[node]
It wouldn't work since the set of leaves may change. For example, in the optimal answer we may use operation on a vertex V and on its parent after that, but there might exist another vertex which would decrease answer by more than V.
Got it, my bad so dp is the only way?
Yes, as far as I know.
I think this works fine. If some mistake is there please rectify.
1) You are outputting dp[1][k], instead of the answer.
2) While iterating over 0 <= i <= k should go in descending order to avoid taking one subtree several times.
3) dp[v][sz[v]] is miscalculated for v with at least 2 children.