| | | | 描述 Description | | | Ural大学有N个职员,编号为1~N。他们有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。每个职员有一个快乐指数。现在有个周年庆宴会,要求与会职员的快乐指数最大。但是,没有职员愿和直接上司一起与会。 | | | |
| | | | 输入格式 Input Format | | | 第一行一个整数N。(1<=N<=6000) 接下来N行,第i+1行表示i号职员的快乐指数Ri。(-128<=Ri<=127) 接下来N-1行,每行输入一对整数L,K。表示K是L的直接上司。 最后一行输入0,0。 | | | |
| | | | 输出格式 Output Format | | | 输出最大的快乐指数。 | | | |
| | | | 样例输出 Sample Output [复制数据] | | | | | | |
| | | | 时间限制 Time Limitation | | | 各个测试点1s
| |
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
int n;//人数
int h[6000];//高兴指数
vector<int> G[6000];//下属
int boss[6000];//老板
int f[60000][2];//以i为根,f[i][1]表示i出席的最大值,f[i][0]表示i不出席的最大值
void dfs(int k)
{
for(int j=0;j<G[k].size();j++)
{
int i=G[k][j];
dfs(i);
//如果老板出席,那么他的手下就不出席
f[k][0]+=max(f[i][0],f[i][1]);
f[k][1]+=f[i][0];
}
f[k][1]+=h[k];
}
int main()
{
while(scanf("%d",&n)==1)
{
for(int i=1;i<=n;i++) scanf("%d",&h[i]);
memset(boss,0,sizeof(boss));
memset(f,0,sizeof(f));
int x,y;
while(scanf("%d%d",&x,&y)==2,x||y)
{
G[y].push_back(x);
boss[x]=y;
}
for(int i=1;i<=n;i++)
{
if(boss[i]==0)//根节点
{
dfs(i);//树形DP
printf("%d/n",max(f[i][0],f[i][1]));
break;
}
}
}
return 0;
}