又是一道树型DP,不过这次是以点带权值,因为根是不确定的,我们可以设个虚根 0 ,因为算是多了一点,所以总点数应该++。
因为是点带权值,所以不用dfs边的数量了,不过有一点虚注意,因为多了一个点,所以j层循环(所选的边数)下界应该是到2的。
#include<iostream>
#include<cstdio>
using namespace std;
int n,m,s,x,y,dp[305][305],head[305];
struct node{
int from,to;
}list[305];
void add(int x,int y){
list[++s].from=head[x];
list[s].to=y;
head[x]=s;
}
void dfs(int x){
for (int i=head[x];i;i=list[i].from){
int v=list[i].to;
dfs(v);
//if (v==fa) continue;
for (int j=m;j>=2;j--)//因为m++
for (int k=1;k<j;k++)
dp[x][j]=max(dp[x][j],dp[x][j-k]+dp[v][k]);
}
}
int main(){
cin>>n>>m;
m++;
for (int i=1;i<=n;i++){
scanf("%d%d",&x,&y);
add(x,i);
dp[i][1]=y;
}
dfs(0);
cout<<dp[0][m];
return 0;
}