比赛 2009noip模拟试卷 评测结果 AAAAAAAAAA
题目名称 火车站饭店 最终得分 100
用户昵称 槿柒 运行时间 0.427 s
代码语言 C++ 内存使用 17.09 MiB
提交时间 2016-10-09 17:42:36
显示代码纯文本
#include<stdio.h>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=100005;

struct Edge{
	int to,next;
}e[maxn<<1];

int n,len=0,w[maxn],head[maxn],son[maxn][55],f[maxn][2];
bool flag[maxn];

void Insert(int x,int y){
	len++;e[len].to=y;e[len].next=head[x];head[x]=len;
}

void Build(int x){//因为不只有两个儿子,且相连关系不可改变,所以不可转成二叉树 
	flag[x]=1;
	for(int i=head[x];i!=-1;i=e[i].next){
		int j=e[i].to;
		if(flag[j])continue;
		son[x][++son[x][0]]=j;
		Build(j);
	}
}

int Dp(int x,int ff){//0不选,1选 
	if(f[x][ff])return f[x][ff];
	if(ff==1)f[x][ff]=w[x];//如果选x,则先加上x的值 
	else f[x][ff]=0;//不选为0 
	if(ff){
		for(int i=1;i<=son[x][0];i++){
			f[x][1]+=(Dp(son[x][i],0));//选x则不选儿子,加等于是因为之前已经加上了w[x] 
		}
	}
	else{
		for(int i=1;i<=son[x][0];i++){
			f[x][0]+=max(Dp(son[x][i],0),Dp(son[x][i],1));//加等于!因为不知一个儿子,每个儿子的值都要加上 
		}
	}
	return f[x][ff];
}

int Nymph()
{
	freopen("profitz.in","r",stdin);
	freopen("profitz.out","w",stdout);
	memset(head,-1,sizeof head);
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d",&w[i]);
	int x,y;
	for(int i=1;i<n;i++){
		scanf("%d%d",&x,&y);
		Insert(x,y);Insert(y,x);
	}
	Build(1);
	int ans=max(Dp(1,1),Dp(1,0));
	printf("%d",ans);
	return 0;
}
int nymph=Nymph();
int main(){;}