题目链接
因为想要保留子结点,必须保留父结点,因此有依赖关系。将每个结点看成一个物品,体积为1,价值为该结点与父亲边上苹果数,可用有依赖背包求解。
#include <iostream>
#include <cstring>
using namespace std;
const int N = 105;
int n, q, f[N][N];
int nxt[2 * N], lnk[2 * N], val[2 * N], head[2 * N], idx;
bool visit[N];
void add(int a, int b, int w) {
lnk[idx] = b;
val[idx] = w;
nxt[idx] = head[a];
head[a] = idx ++ ;
}
void dfs(int node, int w) {
visit[node] = true;
for (int i = head[node]; i != -1; i = nxt[i]) {
int son = lnk[i];
if (!visit[son]) {
dfs(son, val[i]);
for (int j = q - 1; j >= 0; j -- ) {
for (int k = 0; k <= j; k ++ )
f[node][j] = max(f[node][j], f[node][j - k] + f[son][k]);
}
}
}
for (int j = q; j >= 1; j -- ) f[node][j] = f[node][j - 1] + w;
}
int main() {
scanf("%d%d", &n, &q);
q += 1; // 包括结点1共保留q+1个点,q条边
int a, b, w;
memset(head, -1, sizeof head);
for (int i = 1; i < n; i ++ ) {
scanf("%d%d%d", &a, &b, &w);
add(a, b, w);
add(b, a, w);
}
dfs(1, 0);
printf("%d\n", f[1][q]);
return 0;
}