思路
树形dp基础题型,dp[i][0]表示i不选中时的最大快乐指数,dp[i][1]表示i选中时的最大快乐指数,
所以我们只要先找到一个根节点,然后向下dfs,dp[root][0]和dp[root][1]的较大值就是答案。
从下往上状态转移,我们先搜索到叶子节点,然后求出父节点的dp[i][0]和dp[i][1]就好了。
规则相当简单:dp[fa][1]只能加dp[son][0],而dp[fa][0]可以加dp[son][0]和dp[son][1]
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=10005;
struct E{
int next,to;
}edge[maxn];
int n,l,k,h[maxn],ans=0;
int cnt=0,head[maxn],fa[maxn],dp[maxn][2];
void addedge(int from,int to){
edge[++cnt].next=head[from];
edge[cnt].to=to;
head[from]=cnt;
}
void dfs(int node,int pre){
for(int i=head[node];i;i=edge[i].next){
int to=edge[i].to;
if(to==pre) continue;
dfs(to,node);
dp[node][0]+=max(dp[to][1],dp[to][0]);
dp[node][1]+=dp[to][0];
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) fa[i]=i;
for(int i=1;i<=n;i++) scanf("%d",&dp[i][1]);
for(int i=1;i<n;i++){
scanf("%d%d",&l,&k);
addedge(k,l);
fa[l]=k;
}
for(int i=1;i<=n;i++){
if(fa[i]==i){
dfs(i,0);
printf("%d",max(dp[i][1],dp[i][0]));
return 0;
}
}
return 0;
} 
京公网安备 11010502036488号