题目描述
某大学有(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]));
}