关于树形dp:递归建树+递归dp;
关于建树:顺序分左右一搜到底 撞南墙方回;
关于二叉苹果树本题:1.注意题意中的坑点 map可能是0 注意初始化-1和make_tree里的判断条件
2.主函数里q++把边数转为结点数
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int n,q;
int map[500][500];
int a[500];
int l[500],r[500];
int as[500][500];
void make_tree(int now) {
for(int i=1;i<=n;i++)
if(map[i][now]>=0) {
l[now]=i;
a[i]=map[i][now];
map[i][now]=map[now][i]=-1;
make_tree(i);
break;
}
for(int i=1;i<=n;i++)
if(map[i][now]>=0) {
r[now]=i;
a[i]=map[i][now];
map[i][now]=map[now][i]=-1;
make_tree(i);
break;
}
}
int dp(int ori,int rest) {
if(rest==0) return 0;
if(r[ori]==0&&l[ori]==0) return a[ori];
if(as[ori][rest]!=0) return as[ori][rest];
for(int il=0;il<=rest-1;il++)
as[ori][rest]=max(as[ori][rest],dp(l[ori],il)+dp(r[ori],rest-il-1)+a[ori]);
return as[ori][rest];
}
void work1() {
make_tree(1);
cout<<dp(1,q);
return ;
}
int main() {
scanf("%d%d",&n,&q);
q++;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
map[i][j]=map[j][i]=-1;
for(int i=1;i<=n-1;i++) {
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
map[x][y]=map[y][x]=z;
}
work1();
return 0;
}