AcWing 1220. 生命之树
原题链接
中等
作者:
Donx
,
2021-03-19 22:08:00
,
所有人可见
,
阅读 322
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 1e5 + 10;
typedef long long LL;
LL f[N];// 以u为根节点的树的集合 ( f[1,2,3,4,...,n]就是所有树的集合,即所有连通块的集合)
// 属性:最大权值
int w[N], h[N], e[N*2], ne[N*2], idx;//e存入度点,ne存地址,idx表示地址用到那了
void add(int a, int b) {
e[idx] = b;
ne[idx] = h[a];
h[a] = idx++;
}
void dfs(int u, int father) {
f[u] = w[u];
for (int i = h[u]; i != -1; i=ne[i]) {
int j = e[i];
if(j == father) continue;// 防止回头,因为此时是以u为根,不能再往上爬
dfs(j, u);//计算f[j];
f[u] += max(0ll, f[j]);
}
}
int main () {
int n;
cin>>n;
memset(h, -1, sizeof h);
for (int i = 1; i <= n; i++) scanf("%d", &w[i]);
for (int i = 0; i < n - 1; i++) {
int a, b;
cin >> a >> b;
add(a, b), add(b, a);
}
dfs(1, -1);// 随便找个点作为总根
LL ans = f[1];
for (int i = 2; i <= n; i++) {
//总根的f不一定最大
ans = max(ans, f[i]);
}
cout << ans << endl;
return 0;
}