这是一道经典的树形dp的题,转移状态实际上就两个
1.
2.
其中v为x的儿子,然后就可以如下写代码了
#include <iostream> #include<stdio.h> #include<string> #include<string.h> #include<map> #include<queue> #include<deque> #include<vector> #include<algorithm> #include<set> #include<cmath> using namespace std; typedef long long ll; const int maxn=6e3+100; const int maxe=4e4+100; const ll inf=1e18; const ll _inf=-1e17; const double pi=acos(-1); const int mod=1e9+7; inline int readii(){ int sgn = 1; int cnt = 0;char ch = getchar(); while (ch < '0' || ch > '9') {if(ch == '-')sgn = -sgn;ch = getchar();} while ('0' <= ch && ch <= '9') {cnt = cnt*10 + (ch-'0');ch = getchar();} return sgn*cnt; } inline int readll(){ int sgn = 1; int cnt = 0;char ch = getchar(); while (ch < '0' || ch > '9') {if(ch == '-')sgn = -sgn;ch = getchar();} while ('0' <= ch && ch <= '9') {cnt = cnt*10 + (ch-'0');ch = getchar();} return sgn*cnt; } int n; int happy[maxn]; ll dp[maxn][2]; vector<int> G[maxn]; ll ans=_inf; void dfs(int x,int fa) { for(int i=0;i<G[x].size();i++) { int v=G[x][i]; if(v==fa) continue; dfs(v,x); dp[x][1]=max(dp[x][1],dp[x][1]+dp[v][0]); dp[x][0]=max({dp[x][0],dp[x][0]+dp[v][1],dp[x][0]+dp[v][0]}); /*注意这个地方,一定要放一起写,不能分开,因为只能在两种中挑一个,分开则变成了可以挑和不挑同时都可以选*/ } // printf("dp[%d][0] = %lld, dp[%d][1] = %lld\n",x,dp[x][0],x,dp[x][1]); ans=max(ans,dp[x][0]); ans=max(ans,dp[x][1]); } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) {scanf("%d",&happy[i]);dp[i][0]=0;dp[i][1]=happy[i];} int L,k; for(int i=1;i<=n-1;i++) { scanf("%d%d",&L,&k); G[L].push_back(k); G[k].push_back(L); } scanf("%d%d",&L,&k); dfs(1,-1); printf("%lld\n",ans); return 0; }