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

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\n",max(f[zy][1],f[zy][0]));
}
posted @ 2019-01-28 10:29  ZhaoChongyan  阅读(122)  评论(0编辑  收藏  举报