设 fi,j 表示以 i 为根的子树内选 j 个数能获得的最大价值,
可得转移 fi,j = max$$\left\{f_{i,j}, f_{i,j-k}+ f_{y,k}\right\} + valx
不知道上式有什么问题......求dalao指教 QwQ
#include<cstdio>
using namespace std;
const int maxn = 310;
int n,m;
int f[maxn][maxn];
int head[maxn], ver[maxn], nxt[maxn], tot, size[maxn];
int val[maxn];
inline int max(int a,int b){return a>b?a:b;}
inline int min(int a,int b){return a<b?a:b;}
void dfs(int x){
size[x] = 1;
//f[x][0] = val[x];
for(int i=head[x];i;i=nxt[i]){
int y=ver[i];
dfs(y);
size[x] += size[y];
for(int j=size[x];j>=1;j--){ //一共选j个
for(int k=0;k<=min(j-1,size[y]);k++)//其中在子树y中选了k个,k!=j的原因是只有取根节点x才能取子树y,当k==j时相当于没取根节点x
f[x][j] = max(f[x][j], f[x][j-k] + f[y][k]);
f[x][j] += val[x];
}
}
}
inline void addline(int u,int v){
ver[++tot] = v, nxt[tot] = head[u], head[u] = tot;
}
int read(){
int num=0;
char c=getchar();
while(c<'0'||c>'9') c=getchar();
while('0'<=c&&c<='9') num=num*10+(c&15), c=getchar();
return num;
}
int main(){
n=read(), m=read();
for(int i=1;i<=n;i++){
int ui=read();
val[i]=read();
addline(ui,i);
}
dfs(0);
printf("%d",f[0][m+1]);
return 0;
}