P1122 最大子树和
题目链接
大致题意:
总结来说,给出n个点,n-1条边,构成一棵树.
每个节点有一个权值,可以为负,选择树中联通的一部分,使得该子树权值和最
大,输出最大的权值和.
解题思路:
树形dp入门题
定义状态方程:f[i]表示为以i节点为根的最大权值和
从贪心的角度出发,遇到以i节点为根的子树和为负值,肯定不取.
那么,我们的转移方程就可以写出来了
f[u]+=max(0,f[v]) (v是属于u的子节点)
AC代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 2e4 + 10;
int w[N]; //节点值
vector<int>e[N];
int f[N], res; //f数组表示 以i节点为根的最大美丽值加和
void dfs(int u, int fa) {
f[u] = w[u];
for (auto& v : e[u]) {
if (v == fa)continue;
dfs(v, u);
f[u] += max(0, f[v]);
}
res = max(res, f[u]);
}
int main(void)
{
int n; cin >> n;
for (int i = 1; i <= n; ++i)cin >> w[i];
for (int i = 1; i < n; ++i) {
int a, b; cin >> a >> b;
e[a].push_back(b);
e[b].push_back(a);
}
dfs(1, -1);
cout << res << endl;
return 0;
}