Description
Ural大学有 个职员,编号为 ~ 。他们有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。每个职员有一个快乐指数。现在有个周年庆宴会,要求与会职员的快乐指数最大。但是,没有职员愿和直接上司一起与会。
Input
第一行一个整数
。
接下来
行,第
行表示i号职员的快乐指数
。
接下来
行,每行输入一对整数
,
。表示
是
的直接上司。
最后一行输入0,0。
Output
输出最大的快乐指数。
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
解题思路
用邻接表存,
为邻接表,
指向员工,
储存职员链的起始位置。
(不知道链表的,出门左拐百度)
设
为第
个职员参加晚会的最优值
为第
个职员不参加晚会的最优值
- 第 个职员参加,Ta的所有直接员工都不能参加,则
- 第
个职员不参加,Ta的员工可参加可不参加,取开心值最大值,则
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=6010;
struct DT{
int y;
int next;
}a[maxn];
int b[maxn],n,s[maxn],f[maxn][2],num,Gun;
bool t[maxn];
void dp(int root){
f[root][1]=s[root];//初始开心值为自己
for(int i=b[root];i;i=a[i].next){
dp(a[i].y);
f[root][1]=f[root][1]+f[a[i].y][0];//参加
f[root][0]=f[root][0]+max(f[a[i].y][0],f[a[i].y][1]);//不参加
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&s[i]);
for(int i=1;i<n;i++){
int k,l;
scanf("%d%d",&l,&k);//k是上司,l是员工
t[l]=1;
a[++num].y=l;
a[num].next=b[k];
b[k]=num;//存入链表
}
for(int i=1;i<=n;i++){
if(!t[i]){//没有上司的顶头上司(%%%)
dp(i);
Gun=max(Gun,max(f[i][0],f[i][1]));//最后的答案也要取开心值最大值
}
}
printf("%d",Gun);
}