题目中的意思翻译过来其实是在一颗数上相邻的节点只能选择一个,那么最大的和为多少。
那么对于每一个节点来说就有选与不选两种状态: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;
}

京公网安备 11010502036488号