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;
}

浙公网安备 33010602011771号