Problem: [Ural1039]没有上司的晚会
Time Limit: 1 Sec Memory Limit: 128 MB
[Submit][Status][Web Board]
Description
有个公司要举行一场晚会。
为了能玩得开心,公司领导决定:如果邀请了某个人,那么一定不会邀请他的上司
(上司的上司,上司的上司的上司……都可以邀请)。
每个参加晚会的人都能为晚会增添一些气氛,求一个邀请方案,使气氛值的和最大。
Input
第1行一个整数N(1<=N<=6000)表示公司的人数。
接下来N行每行一个整数。第i行的数表示第i个人的气氛值x(-128<=x<=127)。
接下来每行两个整数L,K。表示第K个人是第L个人的上司。
输入以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
Code
#include <cstdio>
#include <algorithm>
using namespace std;
int f[10010][2],v[10010],h[10010],n,cnt,head[100001];
struct edge {
int pre,nxt;
} e[200001];
void add(int x,int y) {
e[++cnt]=edge {y,head[x]};
head[x]=cnt;
}
void dp(int x) {
f[x][0]=0;
f[x][1]=h[x];
for(int i=head[x]; i; i=e[i].nxt) {
int y=e[i].pre;
dp(y);
f[x][0]+=max(f[y][0],f[y][1]);
f[x][1]+=f[y][0];
}
}
int main() {
scanf("%d",&n);
for(int i=1; i<=n; i++) scanf("%d",h+i);
for(int i=1,x,y;; i++) {
scanf("%d %d",&x,&y);
if(x==0 && y==0) break;
v[x]=1;
add(y,x);
}
int root;
for(int i=1; i<=n; i++)
if(!v[i]) {
root=i;
break;
}
dp(root);
printf("%d
",max(f[root][0],f[root][1]));
}