题目大意:某公司有 N 个成员,编号为 1~N 。他们有从属关系,也就是说他们的关系就像一棵以公司总经理为根的树形结构,父结点就是子结点的直接上司。每个成员有一个快乐指数。现在有个周年庆宴会,要求与会成员的快乐指数最大。但是,没有成员愿和直接上司一起与会,也就是说要保证参加宴会的人中没有一个人是另一个人的直接上司。
考察点:树形DP
思路分析:f[x,0]表示x不参加能达到的最多人数,f[x,1]表示x参加能达到的最多人数,那么f[x][0]=max(f[x.son][0],f[x.son][1])
F[x][1]=max(f[x.son][0]+r[x]);
#include<stdio.h>
#define max(a,b) (a)>(b)? (a):(b)
int n,l;
int r[100010];int head[100010];
long int f[100010][2];int v[100010];
struct edge{
int p,next;
}edge[200020];
void dfs(int x)
{
int j,k;long int c;
v[x]=0;
if (head[x]==0)
{
f[x][0]=0;
f[x][1]=r[x];
return;
}
k=head[x];
while (k!=0)
{
j=edge[k].p;
if (v[j]==1) dfs(j);
c=max(f[j][0],f[j][1]);
f[x][0]=max(f[x][0],f[x][0]+c);
f[x][1]=max(f[x][1],f[x][1]+f[j][0]);
k=edge[k].next;
}
f[x][1]+=r[x];
}
void addedge(int x,int y)
{
l++;
edge[l].p=y;
edge[l].next=head[x];
head[x]=l;
}
int main()
{
int i,j,k;
while (~scanf("%d",&n))
{
memset(v,0,sizeof(v));
memset(f,0,sizeof(f));
memset(head,0,sizeof(head));
l=0;
for (i=1;i<=n;i++)
scanf("%d",&r[i]);
for (i=1;i<=n-1;i++)
{
scanf("%d%d",&j,&k);
addedge(k,j);
v[j]=1;
}
for (i=1;i<=n;i++)
if (v[i]==0)
{
addedge(n+1,i);v[i]=1;
}
dfs(n+1);
printf("%d\n",f[n+1][0]);
}
return 0;
}