思路
树形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; }