题目描述 Description
Ural大学有N个职员,编号为1~N。他们有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。每个职员有一个快乐指数。现在有个周年庆宴会,要求与会职员的快乐指数最大。但是,没有职员愿和直接上司一起与会。
输入描述 Input Description
第一行一个整数N。(1<=N<=6000)
接下来N行,第i+1行表示i号职员的快乐指数Ri。(-128<=Ri<=127)
接下来N-1行,每行输入一对整数L,K。表示K是L的直接上司。
最后一行输入0,0。
输出描述 Output Description
Ural大学有N个职员,编号为1~N。他们有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。每个职员有一个快乐指数。现在有个周年庆宴会,要求与会职员的快乐指数最大。但是,没有职员愿和直接上司一起与会。
输入描述 Input Description
第一行一个整数N。(1<=N<=6000)
接下来N行,第i+1行表示i号职员的快乐指数Ri。(-128<=Ri<=127)
接下来N-1行,每行输入一对整数L,K。表示K是L的直接上司。
最后一行输入0,0。
输出描述 Output Description
输出最大的快乐指数。
树上动规。
f表示这个人去,以他为根的子树的最大收益。
g表示这个人不去。
f[i]=sum{g[j]},j是i的儿子。
g[i]=sum{max(g[j],g[i])},j是i的儿子。
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
struct node
{
int fa,f,g,v;
vector<int> chi;
}t[6010];
int root,n;
int max(int x,int y)
{
return x>y?x:y;
}
void cal(int p)
{
if (t[p].f) return;
int i,j,k,x,y;
t[p].f=t[p].v;
t[p].g=0;
if (!t[p].chi.size()) return;
vector<int>::iterator it;
for (it=t[p].chi.begin();it!=t[p].chi.end();it++)
{
x=*it;
cal(x);
t[p].f+=t[x].g;
t[p].g+=max(t[x].f,t[x].g);
}
}
int main()
{
int i,j,k,x,y;
scanf("%d",&n);
for (i=1;i<=n;i++)
scanf("%d",&t[i].v);
for (i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
t[x].fa=y;
t[y].chi.push_back(x);
}
for (i=1;i<=n;i++)
if (!t[i].fa)
{
cal(i);
printf("%d\n",max(t[i].f,t[i].g));
}
}