LG P1352 没有上司的舞会

题目描述

某大学有(n)个职员,编号为(1sim n).他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数(r_i),但是呢,如果某个职员的上司来参加舞会了,那么这个职员就无论如何也不肯来参加舞会了.所以,请你编程计算,邀请哪些职员可以使快乐指数最大,求最大的快乐指数.

分析

树形DP入门题.设(dp[x][0])表示以(x)为根的子树,且(x)不参加舞会的最大快乐值,(dp[x][1])表示以(x)为根的子树,且(x)参加了舞会的最大快乐值,则

[dp[x][0]=sum_{yin son(x)}max{dp[y][0],dp[y][1]};\ dp[x][1]=sum_{yin son(x)}max{dp[y][0]}+r_x ]

记忆化搜索即可.

Code

const int Maxn=6007;

int f[Maxn][2];
int n,root;
int nxt[Maxn<<1],head[Maxn<<1],indeg[Maxn];

inline void DFS(int x)
{
    for(int i=head[x];i;i=nxt[i])
        DFS(i),
        f[x][1]=max(max(f[x][1],f[i][0]+f[x][1]),f[i][0]),
        f[x][0]=max(max(f[x][0],f[i][1]+f[x][0]),max(f[i][1],f[i][0]));
}

int main()
{
    scanf("%d",&n);

    for(int i=1;i<=n;++i)
        scanf("%d",&f[i][1]);

    for(int i=1,x,y;i<=n;++i) 
         scanf("%d%d",&y,&x),
         ++indeg[y],
         nxt[y]=head[x],
         head[x]=y;
         
    for(int i=1;i<=n;i++)
        if(indeg[i]==0) 
       {
            root=i;
            break;
       }
 
    DFS(root);   
    printf("%d",max(f[root][1],f[root][0]));
}
原文地址:https://www.cnblogs.com/Anverking/p/solution-lgp1352.html