Solution - P2015 二叉苹果树

思路

就是一个分组背包上树,以子节点的结果当作父节点的物品。然后做一个化边权为点权。

于是没了。

#include <bits/stdc++.h>
#define rint register int
#define rllong register long long
#define llong long long
#define N 105
using namespace std;

int dp[N][N];
int to[N<<1], val[N<<1], nxt[N<<1], head[N], gsiz;
#define mkarc(u,v,w) (++gsiz,to[gsiz]=v,val[gsiz]=w,nxt[gsiz]=head[u],head[u]=gsiz)
int a[N], siz[N];
int n, m;

inline void dfs1(rint u, rint fa){
	siz[u] = 1;
	for(rint i = head[u]; i; i = nxt[i]){
		rint v = to[i];
		if(v == fa) continue;
		a[v] = val[i];
		dfs1(v, u);
		siz[u] += siz[v];
	}
	return;
}

inline void dfs2(rint u, rint fa){
	dp[u][1] = a[u];
	for(rint i = head[u]; i; i = nxt[i]){
		rint v = to[i];
		if(v == fa) continue;
		dfs2(v, u);
		for(rint j = min(siz[u], m); j >= 1; --j)
			for(rint k = 1; k <= min(siz[v], j-1); ++k)
				dp[u][j] = max(dp[u][j], dp[u][j-k]+dp[v][k]);
	}
	return;
}

int main(){
	scanf("%d %d", &n, &m), ++m;
	for(rint i = 1; i < n; ++i){
		rint u, v, w;
		scanf("%d %d %d", &u, &v, &w);
		mkarc(u, v, w), mkarc(v, u, w);
	}
	dfs1(1, 0);
	dfs2(1, 0);
	printf("%d", dp[1][m]);
	return 0;
}

posted @ 2025-04-20 15:10  Hootime  阅读(4)  评论(0)    收藏  举报