嘛。
经典的树上带权最大独立集问题。
小心不要被不带提示的multi-case坑。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<cctype>
#include<ctime>
using namespace std;
#define add_edge(a,b) nxt[++tot]=head[a],head[a]=tot,to[tot]=b
int n, tot, w[6005], head[6005], nxt[12005], to[12005], f[6005][2];
void dfs(int x, int fa) {
for (int i = head[x]; i; i = nxt[i]) {
if (to[i]==fa) continue;
dfs(to[i], x);
f[x][0] += max(f[to[i]][1], f[to[i]][0]);
f[x][1] += f[to[i]][0];
}
f[x][1] += w[x];
}
int main() {
while (~scanf("%d", &n)) {
memset(f,0,sizeof(f));
tot = 0;
memset(head, 0, sizeof(head));
for (int i = 1; i <= n; ++i) {
scanf("%d", &w[i]);
}
int a, b;
while (~scanf("%d%d", &a, &b)) {
if (!a && !b) break;
add_edge(a,b);
add_edge(b,a);
}
dfs(1, 0);
printf("%d\n",max(f[1][0],f[1][1]));
}
return 0;
}