这题有树 有 d p dp dp 所以就是树 d p dp dp咯
设
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]表示在节点
i
i
i下面取
j
j
j个节点可以获得的苹果最大值
l
s
[
i
]
ls[i]
ls[i]表示
i
i
i的左儿子节点
,
,
,
r
s
[
i
]
rs[i]
rs[i]表示
i
i
i的右儿子节点
这两个在
d
f
s
dfs
dfs建树的过程中就可以维护
我们用记忆化搜索来实现
d
p
dp
dp
s
f
d
(
i
,
j
)
sfd(i,j)
sfd(i,j)的返回值表示在节点
i
i
i下面取
j
j
j个节点可以获得的苹果最大值
所以转移方程如下:
k
j
=
{
d
p
[
i
]
[
j
]
=
m
a
x
{
d
p
[
i
]
[
j
]
,
s
f
d
(
r
s
[
i
]
,
j
−
1
)
+
r
v
[
i
]
}
,
k
=
0
d
p
[
i
]
[
j
]
=
m
a
x
{
d
p
[
i
]
[
j
]
,
s
f
d
(
l
s
[
i
]
,
j
−
1
)
+
l
v
[
i
]
}
,
k
=
j
d
p
[
i
]
[
j
]
=
m
a
x
{
d
p
[
i
]
[
j
]
,
s
f
d
(
l
s
[
i
]
,
k
−
1
)
+
s
f
d
(
r
s
[
i
]
,
j
−
k
−
1
)
+
l
v
[
i
]
+
r
v
[
i
]
}
;
,
0
<
k
<
j
k_j=\begin{cases} dp[i][j]=max\{dp[i][j],sfd(rs[i],j-1)+rv[i]\} ,k=0\\ dp[i][j]=max\{dp[i][j],sfd(ls[i],j-1)+lv[i]\} ,k=j\\ dp[i][j]=max\{dp[i][j],sfd(ls[i],k-1)+sfd(rs[i],j-k-1)+lv[i]+rv[i]\}; ,0<k<j\\ \end{cases}
kj=⎩⎪⎨⎪⎧dp[i][j]=max{dp[i][j],sfd(rs[i],j−1)+rv[i]},k=0dp[i][j]=max{dp[i][j],sfd(ls[i],j−1)+lv[i]},k=jdp[i][j]=max{dp[i][j],sfd(ls[i],k−1)+sfd(rs[i],j−k−1)+lv[i]+rv[i]};,0<k<j
#include<bits/stdc++.h>
using namespace std;
inline void read(int &x){
int s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){s=(s<<3)+(s<<1)+(ch&15);ch=getchar();}
x=s*w;
}
struct node
{
int to,val,nxt;
}edge[300];
int n,m,x,y,z,cnt,head[110],ls[110],rs[110],lv[110],rv[110],dp[110][110];
inline void addedge(int u, int v, int w){
edge[++cnt].to=v,edge[cnt].val=w;
edge[cnt].nxt=head[u],head[u]=cnt;
}
inline void superadd(int u, int v, int w){
addedge(u,v,w),addedge(v,u,w);
}
void dfs(int u, int fa){
for(int i=head[u];i;i=edge[i].nxt){
int vv=edge[i].to;
if(vv==fa)continue;
if(!ls[u])ls[u]=vv,lv[u]=edge[i].val;
else rs[u]=vv,rv[u]=edge[i].val;
dfs(vv,u);
}
}
int sfd(int i, int j){
if(!ls[i]&&!rs[i])return 0;
if(dp[i][j])return dp[i][j];
if(j==0)return 0;
for(int k=0;k<=j;k++){
if(k==0)dp[i][j]=max(dp[i][j],sfd(rs[i],j-1)+rv[i]);
else if(k==j)dp[i][j]=max(dp[i][j],sfd(ls[i],j-1)+lv[i]);
else dp[i][j]=max(dp[i][j],sfd(ls[i],k-1)+sfd(rs[i],j-k-1)+lv[i]+rv[i]);
}
return dp[i][j];
}
int main(){
read(n),read(m);
for(int i=1;i<n;i++)read(x),read(y),read(z),superadd(x,y,z);
dfs(1,0);
printf("%d\n",sfd(1,m));
}