树上DP - 最大权连通子树 - 洛谷P1122 - 最大子树和

这道题想了好久。看到这篇题解后瞬间懂了。关键理解这句话:选择哪个点为根对结果没有影响,毕竟任意连通分量在任意时刻总是可以看成一颗以某个点为根的数

一想通后,这个题就和普通的树上dp没有任何区别了。

代码:

#include <iostream>
#include <vector>
#define MAX(a,b) (a>b?a:b)
#define Maxsize 16000+1
using namespace std;
bool vis[Maxsize];
int dp[Maxsize];
vector<int> vec[Maxsize];
void dfs(int root){
    for (auto it = vec[root].begin(); it != vec[root].end(); it++) {
        if(!vis[*it]){
            vis[*it] = true;
            dfs(*it);
            vis[*it] = false;
        }
    }
    
    for (auto it = vec[root].begin(); it != vec[root].end(); it++) {
        if(!vis[*it]){
            dp[root] += MAX(dp[*it],0);
        }
    }
}
int main(){
    int n;
    int a,b;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> dp[i];
    }
    for (int i = 1; i < n; i++) {
        cin >> a >> b;
        vec[a].push_back(b);
        vec[b].push_back(a);
    }
    vis[1] = true; // 注意初始化根为true
    dfs(1); 
    int ans = -0x3fffffff;
    for (int i = 1; i <= n; i++) {
        ans = MAX(ans,dp[i]);
    }
    cout << ans;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/popodynasty/p/12510052.html