[模版]最大子樹和 題解
阿新 • • 發佈:2022-02-11
[模版]最大子樹和 題解
前置芝士
題目大意
給出一棵樹,上面有權值, 求這個數的子樹的最大權值和。
解
模板題,就是樹上DP。
可以想到只要這個樹的子樹的權值大於0就可以選擇,即加上這個權值。
所以這個DP的轉移方程是 \(f_i=\sum_{i=1}^nf_{a_i}[{f_{a_i}}>0]\)
其中 \(n\) 表示這個子樹大小,\(a_i\) 表示這個子樹的子節點。
#include <bits/stdc++.h> using i64 = long long; constexpr int N = 16010; struct node { int dis, next; } edge[N << 1]; int head[N + 1], siz; inline void add(int from, int dis) { edge[++siz].dis = dis; edge[siz].next = head[from]; head[from] = siz; } int f[N + 1]; int main() { std::ios::sync_with_stdio(false); std::cin.tie(0), std::cout.tie(0); int n; std::cin >> n; for (int i = 1; i <= n; i++) { std::cin >> f[i]; } for (int i = 1; i < n; i++) { int u, v; std::cin >> u >> v; add(u, v); add(v, u); } int ans = -2147483647; std::function <void(int, int)> dfs = [&](int u, int fa) { for (int i = head[u]; i; i = edge[i].next) { int v = edge[i].dis; if (v != fa) { dfs(v, u); f[u] += (f[v] > 0 ? f[v] : 0); } } ans = std::max(ans, f[u]); }; dfs(1, 0); std::cout << ans << std::endl; return 0; }