记录编号 269173 评测结果 AAAAA
题目名称 [HZOI 2016] 搜城探宝 最终得分 100
用户昵称 Gravatarliu_runda 是否通过 通过
代码语言 C++ 运行时间 0.002 s
提交时间 2016-06-13 11:19:39 内存使用 0.35 MiB
显示代码纯文本
#include<cstdio>
#include<cctype>
int read(){
	char ch;int x;bool minus=false;
	while(ch=getchar(),!isdigit(ch)&&ch!='-');
	if(ch=='-'){
		minus=true;
		ch=getchar();
	}
	x=ch-'0';
	while(ch=getchar(),isdigit(ch))x=x*10+ch-'0';
	return minus?-x:x;
}
const int maxn=25;
struct edge{
	int to,next;
}lst[maxn<<2];int len=1;
int first[maxn];
void addedge(int a,int b){
	lst[len].to=b;
	lst[len].next=first[a];
	first[a]=len++;
}
int w[maxn],p[maxn],lch[maxn],rch[maxn];
int f[maxn][maxn][maxn];
bool vis[maxn];
void dfs1(int rt){
	for(int pt=first[rt];pt;pt=lst[pt].next){
		if(lst[pt].to==p[rt])continue;
		p[lst[pt].to]=rt;
		if(lch[rt])rch[rt]=lst[pt].to;
		else lch[rt]=lst[pt].to;
		dfs1(lst[pt].to);
	}
}
int n,k;
int max(int a,int b){
	return a>b?a:b;
}
void dfs2(int x){
	if(vis[x])return;
	vis[x]=true;
	if(!lch[x]){//叶节点 
		for(int i=0;i<=n;++i){//不得进入i 
			if(i==x)continue;
			for(int j=1;j<=k;++j){//j把钥匙 
				f[x][i][j]=w[x];
			}
		}
	}else if(!rch[x]){//仅左子 
		dfs2(lch[x]);
		for(int i=0;i<=n;++i){//不得进入i 
			if(i==x)continue; 
			for(int j=1;j<=k;++j){//j把钥匙 
				f[x][i][j]=f[lch[x]][i][j-1]+w[x];
			}
		}
	}else{
		dfs2(lch[x]);dfs2(rch[x]);
		for(int i=0;i<=n;++i){
			if(i==x)continue;
			for(int j=1;j<=k;++j){
				for(int l=0;l<j;++l){//左子使用几把钥匙 
					f[x][i][j]=max(f[x][i][j],w[x]+f[lch[x]][i][l]+f[rch[x]][i][j-1-l]);
				}
			}
		}
	}
}
int main(){
	freopen("hzoi_key.in","r",stdin);
	freopen("hzoi_key.out","w",stdout);
	n=read();k=read()+1;
	int a,b;
	for(int i=1;i<n;++i){
		a=read();b=read();
		addedge(a,b);
		addedge(b,a);
	}
	for(int i=1;i<=n;++i)w[i]=read();
	dfs1(1);
	for(int i=1;i<=n;++i){
		if(!vis[i])dfs2(i);
	}
	int ans=0;
	for(int i=0;i<=n;++i)//传送到i 
		for(int s=0;s<=k;++s)//s:在起点处使用几个钥匙 
			ans=max(ans,f[1][i][s]+f[i][0][k-s]);
	printf("%d\n",ans);
	fclose(stdin);fclose(stdout);
	return 0;
}