简单树形动态规划(ural 1039 没有上司的晚会)

没有上司的晚会(party)Ural 1039
http://acm.timus.ru/problem.aspx?space=1&num=1039
【问题描述】
有个公司要举行一场晚会。为了能玩得开心,公司领导决定:如果邀请了某个人,那么一定不会邀请他的上司(上司的上司,上司的上司的上司……都可以邀请)。每个参加晚会的人都能为晚会增添一些气氛,求一个邀请方案,使气氛值的和最大。所有员工的编号为1~N。

【输入格式】
第1行一个整数N(1<=N<=6000)表示公司的人数。
接下来N行每行一个整数。第i行的数表示第i个人的气氛值x(-128<=x<=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

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
using namespace std;
struct node
{
    int x,y,next;
}a[110000];int len,last[110000];
void ins(int x,int y)
{
    len++;
    a[len].x=x;a[len].y=y;
    a[len].next=last[x];last[x]=len;
}
int fa[11000],son[11000];
int f[11000][2];
//f[i][j]:1表示这个人来,0表示不来
int v[110000];
void treedp(int x)
{
    f[x][1]=v[x];
    for(int k=last[x];k;k=a[k].next)
    {
        treedp(a[k].y);
    }

    //讨论f[x][1]的情况
    for(int k=last[x];k;k=a[k].next)
    {
        int y=a[k].y;
        f[x][1]+=f[y][0];
        //如果他来的话,那么他的儿子(下属)就不能来;
    }

    //讨论f[x][0]的情况
    f[x][0]=0;
    for(int k=last[x];k;k=a[k].next)
    {
        int y=a[k].y;
        f[x][0]+=max(f[y][1],f[y][0]);
        //如果他不来,那么他的儿子来不来都可以
    }
}
int main()
{
    freopen("party.in","r",stdin);
    freopen("party.out","w",stdout);
    int n;
    scanf("%d",&n);
    memset(f,-1,sizeof(f));
    memset(fa,0,sizeof(fa));
    for(int i=1;i<=n;i++)scanf("%d",&v[i]);
    int xx,yy;len=0;
    memset(last,0,sizeof(last));
    while(scanf("%d%d",&xx,&yy)!=EOF)
    {
        if(xx==0 && yy==0)break;
        ins(yy,xx);fa[xx]=yy;son[yy]=xx;
    }
    int root;//根节点(Boss)
    for(int i=1;i<=n;i++)
        if(fa[i]==0){root=i;break;}
    for(int i=1;i<=n;i++)
    {
        if(son[i]==0)
        {
            f[i][0]=0;
        }
    }
    treedp(root);
    printf("%d\n",max(f[root][1],f[root][0]));
    return 0;
}
阅读更多
版权声明:本文为QQQQqtt原创,但是我猜没有人转载oAo https://blog.csdn.net/qq_36038511/article/details/64124864
个人分类: ural 树形DP
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭