LuoGu-P1122 最大子树和+树形dp入门

传送门

题意:

在一个树上,每个节点都有一个值,求最大的子树和。

思路:

树形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\n", ans);
    return 0;
}
LuoguP1122

 

posted @ 2018-06-10 12:50  ckxkexing  阅读(174)  评论(0编辑  收藏  举报