题意:在一个树上,每个加点都有一个值,求最大的子树和。
思路:据说是树形dp入门。
用dfs,跑一边,回溯的时候求和,若和为负数,则减掉,下次不记录这个节点。
#include <iostream> #include <string> #include <cstring> #include <vector> #include <cstdio> using namespace std; const int maxn = 1e5+9; int a[maxn],dp[maxn],cut[maxn]; vector<int>mp[maxn]; int n,ans = 0; void dfs(int u,int p) { dp[u] = a[u]; for(int i=0; i<mp[u].size(); i++) { int v = mp[u][i]; if(v!=p)dfs(v,u); } for(int i=0; i<mp[u].size(); i++) { int v = mp[u][i]; if(v!=p && cut[v]==0) dp[u] += dp[v]; } if(dp[u] < 0) cut[u] = 1; ans = max ( ans,dp[u]); } int main(){ scanf("%d", &n); for(int i=1; i<=n; i++)scanf("%d", a+i); for(int i=1; i<n; i++) { int u,v; scanf("%d%d", &u, &v); mp[u].push_back(v); mp[v].push_back(u); } dfs(1,-1); printf("%d ", ans); return 0; }