题目中的意思翻译过来其实是在一颗数上相邻的节点只能选择一个,那么最大的和为多少。
那么对于每一个节点来说就有选与不选两种状态:dp[i][0/1]
如果选的话那么以这个节点为根的子树最大和为:dp[i][1] = (f[i]+(所有子树和)dp[u][0]);
那么对于每一个节点来说就有选与不选两种状态:dp[i][0/1]
如果选的话那么以这个节点为根的子树最大和为:dp[i][1] = (f[i]+(所有子树和)dp[u][0]);
如果不选的话那么对于子树来说就有选与不选两种情况,两种情况选大的就行。:dp[i][0] = (所有子树和)max(dp[u][0], dp[u][1]);
//题目中的意思翻译过来其实是在一颗数上相邻的节点只能选择一个,那么最大的和为多少。 //那么对于每一个节点来说就有选与不选两种状态:dp[i][0/1] //如果选的话那么以这个节点为根的子树最大和为:dp[i][1] = (f[i]+(所有子树和)dp[u][0]); //如果不选的话那么对于子树来说就有选与不选两种情况,两种情况选大的就行。:dp[i][0] = (所有子树和)max(dp[u][0], dp[u][1]); #include <bits/stdc++.h> using namespace std; const int maxn = 6000+10; int f[maxn]; vector<int> v[maxn]; int dp[maxn][2]; void dfs(int x, int fa) { int len = v[x].size(); dp[x][1] = f[x]; for (int i=0;i<len;i++) { int next = v[x][i]; if (next == fa) continue; dfs(next, x); dp[x][1] += dp[next][0]; dp[x][0] += max(dp[next][0], dp[next][1]); } } int main() { int n; int x, y; cin>>n; for (int i=1;i<=n;i++) { cin>>f[i]; } for (int i=1;i<=n;i++) { cin>>x>>y; v[x].push_back(y); v[y].push_back(x); } dfs(1, 0); cout<<(dp[1][0]>dp[1][1]? dp[1][0]:dp[1][1]); return 0; }