/*
QUESTION 15: Google OA — Minimizing Tree Contribution by Removing Leaves
Problem Statement:
You are given a rooted tree.
Each node has a value.
Each remaining node contributes:
value[node] * depth[node]
You may remove at most K nodes.
A node can be removed only if it is currently a leaf.
After removing some leaves, their parent may become a new leaf and can be removed later.
Return the minimum possible total contribution after at most K removals.
Hard Constraints:
1 <= N <= 2000
1 <= K <= 500
1 <= value[i] <= 1e9
Example:
values = [3, 8, 2, 7, 5]
edges:
1 - 2
1 - 3
2 - 4
2 - 5
K = 2
Expected Output:
23
Explanation:
Initial contribution:
3*1 + 8*2 + 2*2 + 7*3 + 5*3 = 59
Remove leaves 4 and 5.
Saved contribution:
7*3 + 5*3 = 36
Remaining contribution:
59 - 36 = 23
Brute Force:
Try every possible sequence of leaf removals up to K.
Compute remaining contribution.
Time Complexity:
Exponential
Optimized Approach:
Maximize saved contribution instead of directly minimizing remaining contribution.
dp[u][c] =
maximum contribution removable from subtree u using exactly c removals.
Merge children using knapsack DP.
If the entire subtree of u is removed, it can be removed bottom-up,
so that is also a valid option.
Answer:
initial total contribution - best saved contribution using at most K removals.
Time Complexity:
O(N * K^2)
Space Complexity:
O(N * K)
*/
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
using ll = long long;
int n, K;
vector<vector<int>> tree;
vector<ll> value;
vector<ll> depth;
vector<int> subtreeSize;
vector<ll> subtreeContribution;
vector<vector<ll>> dp;
const ll NEG = -(1LL << 60);
void dfs(int u, int parent) {
subtreeSize[u] = 1;
subtreeContribution[u] = value[u] * depth[u];
dp[u].assign(K + 1, NEG);
dp[u][0] = 0;
for (int v : tree[u]) {
if (v == parent) continue;
depth[v] = depth[u] + 1;
dfs(v, u);
vector<ll> next(K + 1, NEG);
for (int usedU = 0; usedU <= min(K, subtreeSize[u]); usedU++) {
if (dp[u][usedU] == NEG) continue;
for (int usedV = 0;
usedV <= min(K - usedU, subtreeSize[v]);
usedV++) {
if (dp[v][usedV] == NEG) continue;
next[usedU + usedV] =
max(next[usedU + usedV],
dp[u][usedU] + dp[v][usedV]);
}
}
dp[u] = next;
subtreeSize[u] += subtreeSize[v];
subtreeContribution[u] += subtreeContribution[v];
}
if (subtreeSize[u] <= K) {
dp[u][subtreeSize[u]] =
max(dp[u][subtreeSize[u]], subtreeContribution[u]);
}
}
long long minimizeTreeContribution(vector<int>& values,
vector<vector<int>>& edges,
int k) {
n = values.size();
K = k;
value.assign(n, 0);
for (int i = 0; i < n; i++) {
value[i] = values[i];
}
tree.assign(n, {});
for (auto &e : edges) {
int u = e[0] - 1;
int v = e[1] - 1;
tree[u].push_back(v);
tree[v].push_back(u);
}
depth.assign(n, 1);
subtreeSize.assign(n, 0);
subtreeContribution.assign(n, 0);
dp.resize(n);
dfs(0, -1);
ll total = subtreeContribution[0];
ll bestSaved = 0;
for (int c = 0; c <= K; c++) {
bestSaved = max(bestSaved, dp[0][c]);
}
return total - bestSaved;
}
};
int main() {
Solution sol;
vector<int> values = {3, 8, 2, 7, 5};
vector<vector<int>> edges = {
{1, 2},
{1, 3},
{2, 4},
{2, 5}
};
int K = 2;
cout << sol.minimizeTreeContribution(values, edges, K) << endl;
return 0;
}
LyoKUVVFU1RJT04gMTU6IEdvb2dsZSBPQSDigJQgTWluaW1pemluZyBUcmVlIENvbnRyaWJ1dGlvbiBieSBSZW1vdmluZyBMZWF2ZXMKClByb2JsZW0gU3RhdGVtZW50OgpZb3UgYXJlIGdpdmVuIGEgcm9vdGVkIHRyZWUuCkVhY2ggbm9kZSBoYXMgYSB2YWx1ZS4KCkVhY2ggcmVtYWluaW5nIG5vZGUgY29udHJpYnV0ZXM6CnZhbHVlW25vZGVdICogZGVwdGhbbm9kZV0KCllvdSBtYXkgcmVtb3ZlIGF0IG1vc3QgSyBub2Rlcy4KCkEgbm9kZSBjYW4gYmUgcmVtb3ZlZCBvbmx5IGlmIGl0IGlzIGN1cnJlbnRseSBhIGxlYWYuCkFmdGVyIHJlbW92aW5nIHNvbWUgbGVhdmVzLCB0aGVpciBwYXJlbnQgbWF5IGJlY29tZSBhIG5ldyBsZWFmIGFuZCBjYW4gYmUgcmVtb3ZlZCBsYXRlci4KClJldHVybiB0aGUgbWluaW11bSBwb3NzaWJsZSB0b3RhbCBjb250cmlidXRpb24gYWZ0ZXIgYXQgbW9zdCBLIHJlbW92YWxzLgoKSGFyZCBDb25zdHJhaW50czoKMSA8PSBOIDw9IDIwMDAKMSA8PSBLIDw9IDUwMAoxIDw9IHZhbHVlW2ldIDw9IDFlOQoKRXhhbXBsZToKdmFsdWVzID0gWzMsIDgsIDIsIDcsIDVdCmVkZ2VzOgoxIC0gMgoxIC0gMwoyIC0gNAoyIC0gNQpLID0gMgoKRXhwZWN0ZWQgT3V0cHV0OgoyMwoKRXhwbGFuYXRpb246CkluaXRpYWwgY29udHJpYnV0aW9uOgozKjEgKyA4KjIgKyAyKjIgKyA3KjMgKyA1KjMgPSA1OQoKUmVtb3ZlIGxlYXZlcyA0IGFuZCA1LgpTYXZlZCBjb250cmlidXRpb246CjcqMyArIDUqMyA9IDM2CgpSZW1haW5pbmcgY29udHJpYnV0aW9uOgo1OSAtIDM2ID0gMjMKCkJydXRlIEZvcmNlOgpUcnkgZXZlcnkgcG9zc2libGUgc2VxdWVuY2Ugb2YgbGVhZiByZW1vdmFscyB1cCB0byBLLgpDb21wdXRlIHJlbWFpbmluZyBjb250cmlidXRpb24uCgpUaW1lIENvbXBsZXhpdHk6CkV4cG9uZW50aWFsCgpPcHRpbWl6ZWQgQXBwcm9hY2g6Ck1heGltaXplIHNhdmVkIGNvbnRyaWJ1dGlvbiBpbnN0ZWFkIG9mIGRpcmVjdGx5IG1pbmltaXppbmcgcmVtYWluaW5nIGNvbnRyaWJ1dGlvbi4KCmRwW3VdW2NdID0KbWF4aW11bSBjb250cmlidXRpb24gcmVtb3ZhYmxlIGZyb20gc3VidHJlZSB1IHVzaW5nIGV4YWN0bHkgYyByZW1vdmFscy4KCk1lcmdlIGNoaWxkcmVuIHVzaW5nIGtuYXBzYWNrIERQLgoKSWYgdGhlIGVudGlyZSBzdWJ0cmVlIG9mIHUgaXMgcmVtb3ZlZCwgaXQgY2FuIGJlIHJlbW92ZWQgYm90dG9tLXVwLApzbyB0aGF0IGlzIGFsc28gYSB2YWxpZCBvcHRpb24uCgpBbnN3ZXI6CmluaXRpYWwgdG90YWwgY29udHJpYnV0aW9uIC0gYmVzdCBzYXZlZCBjb250cmlidXRpb24gdXNpbmcgYXQgbW9zdCBLIHJlbW92YWxzLgoKVGltZSBDb21wbGV4aXR5OgpPKE4gKiBLXjIpCgpTcGFjZSBDb21wbGV4aXR5OgpPKE4gKiBLKQoqLwoKI2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgpjbGFzcyBTb2x1dGlvbiB7CnB1YmxpYzoKICAgIHVzaW5nIGxsID0gbG9uZyBsb25nOwoKICAgIGludCBuLCBLOwoKICAgIHZlY3Rvcjx2ZWN0b3I8aW50Pj4gdHJlZTsKICAgIHZlY3RvcjxsbD4gdmFsdWU7CiAgICB2ZWN0b3I8bGw+IGRlcHRoOwoKICAgIHZlY3RvcjxpbnQ+IHN1YnRyZWVTaXplOwogICAgdmVjdG9yPGxsPiBzdWJ0cmVlQ29udHJpYnV0aW9uOwoKICAgIHZlY3Rvcjx2ZWN0b3I8bGw+PiBkcDsKCiAgICBjb25zdCBsbCBORUcgPSAtKDFMTCA8PCA2MCk7CgogICAgdm9pZCBkZnMoaW50IHUsIGludCBwYXJlbnQpIHsKICAgICAgICBzdWJ0cmVlU2l6ZVt1XSA9IDE7CiAgICAgICAgc3VidHJlZUNvbnRyaWJ1dGlvblt1XSA9IHZhbHVlW3VdICogZGVwdGhbdV07CgogICAgICAgIGRwW3VdLmFzc2lnbihLICsgMSwgTkVHKTsKICAgICAgICBkcFt1XVswXSA9IDA7CgogICAgICAgIGZvciAoaW50IHYgOiB0cmVlW3VdKSB7CiAgICAgICAgICAgIGlmICh2ID09IHBhcmVudCkgY29udGludWU7CgogICAgICAgICAgICBkZXB0aFt2XSA9IGRlcHRoW3VdICsgMTsKICAgICAgICAgICAgZGZzKHYsIHUpOwoKICAgICAgICAgICAgdmVjdG9yPGxsPiBuZXh0KEsgKyAxLCBORUcpOwoKICAgICAgICAgICAgZm9yIChpbnQgdXNlZFUgPSAwOyB1c2VkVSA8PSBtaW4oSywgc3VidHJlZVNpemVbdV0pOyB1c2VkVSsrKSB7CiAgICAgICAgICAgICAgICBpZiAoZHBbdV1bdXNlZFVdID09IE5FRykgY29udGludWU7CgogICAgICAgICAgICAgICAgZm9yIChpbnQgdXNlZFYgPSAwOwogICAgICAgICAgICAgICAgICAgICB1c2VkViA8PSBtaW4oSyAtIHVzZWRVLCBzdWJ0cmVlU2l6ZVt2XSk7CiAgICAgICAgICAgICAgICAgICAgIHVzZWRWKyspIHsKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICBpZiAoZHBbdl1bdXNlZFZdID09IE5FRykgY29udGludWU7CgogICAgICAgICAgICAgICAgICAgIG5leHRbdXNlZFUgKyB1c2VkVl0gPQogICAgICAgICAgICAgICAgICAgICAgICBtYXgobmV4dFt1c2VkVSArIHVzZWRWXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwW3VdW3VzZWRVXSArIGRwW3ZdW3VzZWRWXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGRwW3VdID0gbmV4dDsKCiAgICAgICAgICAgIHN1YnRyZWVTaXplW3VdICs9IHN1YnRyZWVTaXplW3ZdOwogICAgICAgICAgICBzdWJ0cmVlQ29udHJpYnV0aW9uW3VdICs9IHN1YnRyZWVDb250cmlidXRpb25bdl07CiAgICAgICAgfQoKICAgICAgICBpZiAoc3VidHJlZVNpemVbdV0gPD0gSykgewogICAgICAgICAgICBkcFt1XVtzdWJ0cmVlU2l6ZVt1XV0gPQogICAgICAgICAgICAgICAgbWF4KGRwW3VdW3N1YnRyZWVTaXplW3VdXSwgc3VidHJlZUNvbnRyaWJ1dGlvblt1XSk7CiAgICAgICAgfQogICAgfQoKICAgIGxvbmcgbG9uZyBtaW5pbWl6ZVRyZWVDb250cmlidXRpb24odmVjdG9yPGludD4mIHZhbHVlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjdG9yPHZlY3RvcjxpbnQ+PiYgZWRnZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBrKSB7CiAgICAgICAgbiA9IHZhbHVlcy5zaXplKCk7CiAgICAgICAgSyA9IGs7CgogICAgICAgIHZhbHVlLmFzc2lnbihuLCAwKTsKCiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgICAgICAgICAgdmFsdWVbaV0gPSB2YWx1ZXNbaV07CiAgICAgICAgfQoKICAgICAgICB0cmVlLmFzc2lnbihuLCB7fSk7CgogICAgICAgIGZvciAoYXV0byAmZSA6IGVkZ2VzKSB7CiAgICAgICAgICAgIGludCB1ID0gZVswXSAtIDE7CiAgICAgICAgICAgIGludCB2ID0gZVsxXSAtIDE7CgogICAgICAgICAgICB0cmVlW3VdLnB1c2hfYmFjayh2KTsKICAgICAgICAgICAgdHJlZVt2XS5wdXNoX2JhY2sodSk7CiAgICAgICAgfQoKICAgICAgICBkZXB0aC5hc3NpZ24obiwgMSk7CiAgICAgICAgc3VidHJlZVNpemUuYXNzaWduKG4sIDApOwogICAgICAgIHN1YnRyZWVDb250cmlidXRpb24uYXNzaWduKG4sIDApOwogICAgICAgIGRwLnJlc2l6ZShuKTsKCiAgICAgICAgZGZzKDAsIC0xKTsKCiAgICAgICAgbGwgdG90YWwgPSBzdWJ0cmVlQ29udHJpYnV0aW9uWzBdOwogICAgICAgIGxsIGJlc3RTYXZlZCA9IDA7CgogICAgICAgIGZvciAoaW50IGMgPSAwOyBjIDw9IEs7IGMrKykgewogICAgICAgICAgICBiZXN0U2F2ZWQgPSBtYXgoYmVzdFNhdmVkLCBkcFswXVtjXSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdG90YWwgLSBiZXN0U2F2ZWQ7CiAgICB9Cn07CgppbnQgbWFpbigpIHsKICAgIFNvbHV0aW9uIHNvbDsKCiAgICB2ZWN0b3I8aW50PiB2YWx1ZXMgPSB7MywgOCwgMiwgNywgNX07CgogICAgdmVjdG9yPHZlY3RvcjxpbnQ+PiBlZGdlcyA9IHsKICAgICAgICB7MSwgMn0sCiAgICAgICAgezEsIDN9LAogICAgICAgIHsyLCA0fSwKICAgICAgICB7MiwgNX0KICAgIH07CgogICAgaW50IEsgPSAyOwoKICAgIGNvdXQgPDwgc29sLm1pbmltaXplVHJlZUNvbnRyaWJ1dGlvbih2YWx1ZXMsIGVkZ2VzLCBLKSA8PCBlbmRsOwoKICAgIHJldHVybiAwOwp9