题解:https://zhuanlan.zhihu.com/p/338249705
A Ah, It's Yesterday Once More 脑洞构造 !!!
B Baby's First Suffix Array Problem 后缀树 ???
C Certain Scientific Railgun set 线段树 ???
D Degree of Spanning Tree 生成树的度 ???
E Evil Coordinate ---
F Fireworks 三分 ---
G Go 点双 ???
H Harmonious Rectangle 打表规律 !!!
I Interested in Skiing 几何 !!!
J Just Another Game of Stones 线段树 !!!
K K Co-prime Permutation ---
L Let's Play Curling ---
M Monster Hunter 树形dp !!!
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define ll long long
#define maxn 2010
int head[maxn],nex[2*maxn],go[2*maxn],cnt;
int size[maxn];
ll dp[maxn][maxn][2];
void ct(int x,int y){
nex[++cnt]=head[x];
go[cnt]=y;
head[x]=cnt;
}
int fa[maxn];
ll hp[maxn];
void dfs(int x,int f){
size[x]=1;
for(int i=head[x];i;i=nex[i]){
int now=go[i];
if(now==f)continue;
dfs(now,x);
size[x]+=size[now];
for(int j=size[x];j>0;j--){
for(int k=min(size[now],j);k>0;k--){
int z= j-k;
if(z>size[x]-size[now])break;
dp[x][j][0]=max(dp[x][j][0],dp[now][k][0]+dp[x][j-k][0]);
dp[x][j][0]=max(dp[x][j][0],dp[now][k][1]+dp[x][j-k][0]);
dp[x][j][1]=max(dp[x][j][1],dp[now][k][0]+dp[x][j-k][1]);
dp[x][j][1]=max(dp[x][j][1],dp[now][k][1]+dp[x][j-k][1]-hp[now]);
}
}
}
}
int main(){
ll maxx=-100000000000000ll;
int t;
scanf("%d",&t);
while(t--){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
for(int j=0;j<=n;j++){
dp[i][j][0]=maxx;
dp[i][j][1]=maxx;
}
}
fa[1]=0;
cnt=0;
for(int i=2;i<=n;i++){
scanf("%d",&fa[i]);
ct(i,fa[i]);
ct(fa[i],i);
}
for(int i=1;i<=n;i++){
scanf("%lld",&hp[i]);
}
ll ans=0;
for(int i=1;i<=n;i++){
dp[i][0][0]=0;
dp[i][1][1]=hp[i];
if(fa[i]!=0)dp[i][1][1]+=hp[i];
for(int j=head[i];j;j=nex[j]){
if(go[j]!=fa[i])
dp[i][1][1]+=hp[go[j]];
}
ans=ans+dp[i][1][1];
if(fa[i]!=0)ans=ans-hp[i];
}
dfs(1,0);
/*for(int i=1;i<=n;i++){
for(int j=0;j<=size[i];j++){
printf("dp[%d][%d][0]=%lld dp[%d][%d][1]=%lld\n",i,j,dp[i][j][0],i,j,dp[i][j][1]);
}
}*/
//printf("%d\n",size[1]);
for(int i=0;i<=n;i++){
ll res=ans-max(dp[1][i][0],dp[1][i][1]);
printf("%lld",res);
if(i==n)printf("\n");
else printf(" ");
size[i]=0;
head[i]=0;
}
}
}