[Ural 1039] 没有上司的晚会


题目描述

  Ural周立大学的校长正在筹备学校的80周年纪念聚会。由于学校的职员有不同的职务级别,可以构成一棵以校长为根的人事关系树。每个职员都有一个唯一的整数编号(范围在1到N之间),并且对应一个参加聚会所获得的欢乐度。为了使每个参加聚会者都感到欢乐,校长想设法使每个职员和他(她)的直接上司不会同时参加聚会。
  你的任务是设计一份参加聚会者的名单,使总的欢乐度最高。


输入格式

  输入的第一行是一个整数N,1<= N <= 6000
  以下的N行是对应的N个职员的欢乐度(欢乐度是一个从-128到127之间的整数)
  接着是学校的人事关系树,树的每一行格式如下:
  < L > < K >
  表示第K个职员是第L个职员的直接上司。
  输入以0 0表示结束


输出格式

  输出:参加聚会者获得的最大总欢乐度


样例数据

样例输入

7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
0 0

样例输出

5


题目分析

树型动规,与战略游戏类似
设f[i][0]表示不邀请i的最高欢乐度,f[i][1]表示邀请i的最高欢乐度
若邀请i,则不能邀请i的儿子,若不邀请i,则可邀请i的儿子也可不邀请i的儿子
取个最大值即可


源代码

#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
inline const long long Get_Int() {
    long long num=0,bj=1;
    char x=getchar();
    while(x<'0'||x>'9') {
        if(x=='-')bj=-1;
        x=getchar();
    }
    while(x>='0'&&x<='9') {
        num=num*10+x-'0';
        x=getchar();
    }
    return num*bj;
}
struct Edge {
    int to,next;
} Edge[50005];
int n,cnt=0,Head[50005],f[50005][5],vst[50005],Joy[50005],root;
void AddEdge(int x,int y) {
    cnt++;
    Edge[cnt].to=y;
    Edge[cnt].next=Head[x];
    Head[x]=cnt;
}
void TreeDp(int root) {
    f[root][0]=0;
    f[root][1]=Joy[root];
    for(int i=Head[root]; i; i=Edge[i].next) {
        int Next=Edge[i].to;
        TreeDp(Next);
        f[root][0]=max(f[root][0],max(f[root][0]+f[Next][1],f[root][0]+f[Next][0]));
        f[root][1]=max(f[root][1],f[Next][0]+f[root][1]);
    }
}
int main() {
    n=Get_Int();
    for(int i=1; i<=n; i++)Joy[i]=Get_Int();
    while(true) {
        int x=Get_Int(),y=Get_Int();
        if(x==0&&y==0)break;
        AddEdge(y,x);
        vst[x]=1;
    }
    for(int i=1; i<=n; i++)if(!vst[i])root=i;
    TreeDp(root);
    cout<<max(f[root][0],f[root][1])<<endl;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值