Problem: [Ural1039]没有上司的晚会

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]));
}
原文地址:https://www.cnblogs.com/ZhaoChongyan/p/11740388.html