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

来源:互联网 发布:tina8.0电路仿真软件 编辑:程序博客网 时间:2024/05/13 06:16

没有上司的晚会(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;}
0 0
原创粉丝点击