题意:给定一棵树,在连通块中求所有连通块的数值最大的值
思路
要从一个点遍历到另一个点的最大数值
状态表示
每个点遍历到的连通块的最大值
状态计算
dfs 遍历,但是一般的遍历没法实现每个点遍历所有可能通路,同时是无向图,为了防止往回走,使用有 父节点 的dfs
状态计算为当前节点的所有子节点的加和
实现
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long LL;
const int N = 1e5 + 10, M = 2 * N;
LL f[N];
int w[N];
int h[N], e[M], ne[M], idx;
int n;
void add(int a, int b)
{
e[idx] = b; ne[idx] = h[a]; h[a] = idx ++;
}
//dfs遍历所有节点
void dfs(int x, int father)
{
//每次新遍历到都得是原值
f[x] = w[x];
for(int i = h[x]; i != -1; i = ne[i])
{
int j = e[i];
if(j != father)
{
dfs(j, x);
f[x] += max(0ll, f[j]);
}
}
}
int main()
{
memset(h, -1, sizeof h);
cin >> n;
for(int i = 1; i <= n; i ++)
cin >> 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 ++) ans = max(ans, f[i]);
cout << ans << endl;
return 0;
}