【Tyvj1052】没有上司的舞会

描述 Description

Ural 大学有 N 个职员,编号为 1~N。他们有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。每个职员有一个快乐指数。现在有个周年庆宴会,要求与会职员的快乐指数最大。但是,没有职员愿和直接上司一起与会。

输入格式 InputFormat

第一行一个整数 N(1<=N<=6000)。
接下来 N 行,第 i+1 行表示 i 号职员的快乐指数 Ri(-128<=Ri<=127)。
接下来 N-1 行,每行输入一对整数 L,K。表示 K 是 L 的直接上司。
最后一行输入 0 0。

输出格式 OutputFormat

输出最大的快乐指数。

样例输入 SampleInput

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

样例输出 SampleOutput

5

注释 Hint

简单的树形动规。从下往上做。


Tyvj 1052


代码 Code

#include <stdio.h>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
struct node
{
    int num,dist;
}d[6001];
int a[6001],fa[6001];
int f[6001][2];
int i,j,t,n,m,l,r,k,z,y,x;
bool flag;
void find()
{
    int i,j,t;
    m=0;d[m].num=r;d[m].dist=0;m++;
    j=0;t=0;
    while (t>=j)
    {
        for (i=1;i<=n;i++) if (fa[i]==d[j].num)
        {
            d[++t].num=i;
            d[t].dist=d[j].dist+1;
        }
        j++;
    }
    m=t+1;
}
bool comp(node a,node b)
{
    return a.dist>b.dist;
}
int main()
{
    memset(a,0,sizeof(a));
    memset(fa,0,sizeof(fa));
    memset(f,0,sizeof(f));
    scanf("%d",&n);
    for (i=1;i<=n;i++) scanf("%d",&a[i]);
    for (i=1;i<n;i++)
    {
        scanf("%d%d",&x,&y);
        fa[x]=y;
    }
    scanf("%d%d",&x,&y);
    for (i=1;i<=n;i++) if (fa[i]==0) break;
    r=i;
    find(); 
    sort(d,d+m,comp);
    for (i=0;i<m;i++) 
    {
        x=d[i].num;
        flag=false;
        for (j=0;j<i;j++)
        {
            y=d[j].num;
            if (fa[y]==x)
            {
                f[x][0]+=max(f[y][0],f[y][1]);
                f[x][1]+=f[y][0];
                flag=true;
            }
        }
        f[x][1]+=a[x];
        if (!flag)
        {
            f[x][0]=0;
            f[x][1]=a[x];
        }
    }
    printf("%d\n",max(f[r][1],f[r][0]));
    return 0;
}