题目大意:每个人有一个快乐值,这些人有上下级关系,每个人至多有一个直接上司,规定上司和他的直接下级不能同时出现。求出最大的快乐值之和。
做题思路:通过分析题目,对于每个人都有去和不去2种选择,而由题意可知,一个人去则他的直接上司和直接下属不能去,如果这个人不去,那么他的直接上司和下属可以选择去和不去。那么得到状态方程:
去: dp[1][root]+=dp[0][son];
不去:dp[0][root]+=max(dp[1][son],dp[0][son]);
然后考虑到题目所给的是树形结构,我们使用dfs遍历树由下往上最终比较根节点去和不去的值得最大值。
代码:
#include <iostream>
#include <stdio.h>
#include <vector>
#include <string.h>
using namespace std;
#define maxn 6010
int dp[5][maxn];
int f[maxn];
vector<int>v[maxn];
void dfs(int rt)
{
if(!v[rt].size())return;
for(int i=0;i<v[rt].size();i++){
dfs(v[rt][i]);
dp[1][rt]+=dp[0][v[rt][i]];
dp[0][rt]+=max(dp[0][v[rt][i]],dp[1][v[rt][i]]);
}
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&dp[1][i]);
for(int i=1;i<n;i++){
int l,k;
scanf("%d%d",&l,&k);
v[k].push_back(l);
f[l]++;
}
int h=0;
for(int i=1;i<=n;i++){
if(f[i]==0){
h=i;break;
}
}
dfs(h);
printf("%d\n",max(dp[0][h],dp[1][h]));
return 0;
}