0
点赞
收藏
分享

微信扫一扫

【刷题】动态规划——树形DP:二叉苹果树【有依赖背包问题】

柠檬果然酸 2022-01-13 阅读 24

在这里插入图片描述
题目链接

因为想要保留子结点,必须保留父结点,因此有依赖关系。将每个结点看成一个物品,体积为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;
}
举报

相关推荐

0 条评论