Problem: [Ural1039]没有上司的晚会
Time Limit: 1 Sec Memory Limit: 128 MB
Description
有个公司要举行一场晚会。
为了能玩得开心,公司领导决定:如果邀请了某个人,那么一定不会邀请他的上司
(上司的上司,上司的上司的上司……都可以邀请)。
每个参加晚会的人都能为晚会增添一些气氛,求一个邀请方案,使气氛值的和最大。
Input
第1行一个整数N(1<=N<=6000)表示公司的人数。
接下来N行每行一个整数。第i行的数表示第i个人的气氛值x(-128<=x<=127)。
接下来每行两个整数L,K。表示第K个人是第L个人的上司。
输入以0 0结束。
Output
一个数,最大的气氛值和。
代码如下
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node{
int x,y,next;
}a[100010];
int tot,last[100010];
void add(int x,int y){
tot++;
a[tot].x=x;
a[tot].y=y;
a[tot].next=last[x];
last[x]=tot;
}
int fa[10010],son[10010];
int f[10010][2];
int v[100010];
void dp(int x){
f[x][1]=v[x];
for(int i=last[x];i;i=a[i].next)
dp(a[i].y);
for(int i=last[x];i;i=a[i].next){
int y=a[i].y;
f[x][1]+=f[y][0];
}
f[x][0]=0;
for(int i=last[x];i;i=a[i].next){
int y=a[i].y;
f[x][0]+=max(f[y][1],f[y][0]);
}
}
int main(){
int n;
scanf("%d",&n);
memset(f,-1,sizeof(f));
for(int i=1;i<=n;i++)
scanf("%d",v+i);
int xx,yy;
while(scanf("%d%d",&xx,&yy)!=EOF){
if(xx==0&&yy==0)break;
add(yy,xx);
fa[xx]=yy;
}
int zy=0;
for(int i=1;i<=n;i++)
if(fa[i]==0){
zy=i;
break;
}
dp(zy);
printf("%d
",max(f[zy][1],f[zy][0]));
}