2020南京 icpc


题解: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; 
		}
	}
} 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM