从任一根节点开始dfs,其中fy维护选择当前节点时对应的最大权值,fn维护不选择当前节点时对应的最大权值,最后返回fy[根]与fn[根]的最大值即可。
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include<vector>
using namespace std;
using namespace std;
const int maxn = 100000 + 5;
int fy[maxn]; //表示选择当前节点对应的最大权值
int fn[maxn]; //表示不选择当前节点对应的最大权值
int vis[maxn];
vector<int>v[maxn];
void dfs(int u) {
vis[u] = 1;
int size = v[u].size();
for (int i = 0; i < size; i++) {
if (!vis[v[u][i]]) {
dfs(v[u][i]);
fy[u] += fn[v[u][i]];
fn[u] += max(fn[v[u][i]], fy[v[u][i]]);
}
}
}
int main()
{
int n; cin >> n;
for (int i = 1; i <= n; i++)
scanf("%d", fy + i);
int v1, v2;
for (int i = 1; i < n; i++) {
scanf("%d%d", &v1,&v2);
v[v1].push_back(v2);
v[v2].push_back(v1);
}
dfs(v1);
cout << max(fy[v1], fn[v1]);
return 0;
}