P1122 最大子树和

P1122 最大子树和 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

题目就是要求:树上点权之和最大的一个连通分量

令dp[i]为必须选i节点的情况下,最大的子树点权和

则有转移方程 dp[x]+=max(dp[v],0);

初始化dp[x]=a[x];

注意:最后的答案显然不是dp[1],而是最大的dp[x];

Code:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mp make_pair
#define pb push_back   
#define popb pop_back  
#define fi first
#define se second
const int N=2e4+10;
//const int M=;
//const int inf=0x3f3f3f3f;     
const ll INF=0x3ffffffffffff;
int T,n,a[N],dp[N];
vector<int> g[N];
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*f;
}
void dfs(int x,int fa)
{
    dp[x]=a[x];
    for(auto v:g[x])
    {
        if(v==fa) continue;
        dfs(v,x);
        if(dp[v]>0) dp[x]+=dp[v]; 
    }
}
int main()
{
//    freopen("","r",stdin);
//    freopen("","w",stdout);
    n=read();
    for(int i=1;i<=n;i++) a[i]=read();
    for(int i=1;i<n;i++)
    {
        int u=read(),v=read();
        g[u].pb(v);
        g[v].pb(u);
    }
    dfs(1,0);
    ll ans=-INF;
    for(int i=1;i<=n;i++) ans=max(ans,1LL*dp[i]); 
    printf("%d",ans);
    return 0;
}

 

posted @ 2023-03-12 18:55  QAQ啥也不会  阅读(27)  评论(0编辑  收藏  举报