题目链接: Monster Hunter.
树上DP,本来以为复杂度n3,实际上复杂度是n2的,因为树上每两个节点 x , y ,他们仅会在 lca(x , y)的时候会被统计
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e3+9;
#define inf 0x3f3f3f3f3f3f3f3f
vector<long long>edge[maxn];
long long val[maxn],Size[maxn];
long long dp[maxn][maxn][2],tmp[maxn][2],n;
void dfs(long long x)
{
Size[x] = 1;
for(long long i = 0;i<=n;i++)
{
dp[x][i][0]=dp[x][i][1] = inf;
}
dp[x][0][0] = 0;
dp[x][1][1] = val[x];
for(long long i = 0;i<edge[x].size();i++)
{
long long to = edge[x][i];
dfs(to);
for(long long j = 0;j<=Size[x]+Size[to];j++)
{
tmp[j][0] = tmp[j][1] = inf;
}
for(long long j = 0;j<=Size[x];j++)
{
for(long long k = 0;k<=Size[to];k++)
{
tmp[j+k][0] = min(tmp[j+k][0],min(dp[x][j][0]+dp[to][k][0],dp[x][j][0]+dp[to][k][1]));
tmp[j+k][1] = min(tmp[j+k][1],min(dp[x][j][1]+dp[to][k][0],dp[x][j][1]+dp[to][k][1]+val[to]));
}
}
for(long long j = 0;j<=Size[x]+Size[to];j++)
{
dp[x][j][0] = tmp[j][0];
dp[x][j][1] = tmp[j][1];
}
Size[x]+=Size[to];
}
}
int main()
{
long long i,j,t,num;
scanf("%lld",&t);
while(t--)
{
scanf("%lld",&n);
for(i = 1;i<=n;i++)
{
edge[i].clear();
}
for(i = 2;i<=n;i++)
{
scanf("%lld",&num);
edge[num].push_back(i);
}
for( i = 1;i<=n;i++)
{
scanf("%lld",&val[i]);
}
dfs(1);
for(i = n;i>=0;i--)
{
long long ans = min(dp[1][i][0],dp[1][i][1]);
printf("%lld%c",ans,i==0?'\n':' ');
}
}
return 0;
}