【题目】
题目描述 Description
Ural 大学有 个职员,编号为 ~ 。他们有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。每个职员有一个快乐指数。现在有个周年庆宴会,要求与会职员的快乐指数最大。但是,没有职员愿和直接上司一起与会。
输入描述 Input Description
第一行一个整数 。
接下来 行,第 行表示 号职员的快乐指数 。
接下来 行,每行输入一对整数 。表示 是 的直接上司。
最后一行输入 。
输出描述 Output Description
输出最大的快乐指数。
样例输入 Sample Input
7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
0 0
样例输出 Sample Output
5
【分析】
一道比较简单的树形 题。
用 表示以 为根的子树中, 不参加 参加舞会的最大快乐指数。
那么显然可知(设 为 的儿子):
最后的答案 。
其中 是整棵树的根(不一定是 )。
【代码】
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 6005
using namespace std;
int n,t,root;
int val[N],fa[N],f[N][2];
int first[N],v[N],nxt[N];
void add(int x,int y)
{
nxt[++t]=first[x];
first[x]=t,v[t]=y;
}
void dp(int x)
{
int i,k;
f[x][1]=val[x];
for(i=first[x];i;i=nxt[i])
{
k=v[i],dp(k);
f[x][1]+=f[k][0];
f[x][0]+=max(f[k][1],f[k][0]);
}
}
int main()
{
int x,y,i;
scanf("%d",&n);
for(i=1;i<=n;++i)
scanf("%d",&val[i]);
for(i=1;i<n;++i)
{
scanf("%d%d",&x,&y);
add(y,x),fa[x]=y;
}
for(i=1;i<=n;++i)
if(!fa[i]) root=i;
dp(root);
printf("%d",max(f[root][0],f[root][1]));
return 0;
}