【Codeforces 743D】 Chloe and pleasant prizes【树形dp】

题意:给你一棵带有点权的树,让你求最大的两个不想交的子树的点权和

题解:

树形dp,dp[u]记录u的子树中权值最大的子树的sum值(包括它本身)

具体的状态转移方程很好理解

最主要就是没做过类似题目,可能比较难以想到

#include<set>
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<bitset>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define PB push_back
#define MP make_pair
#define ll long long
#define MS(a,b) memset(a,b,sizeof(a))
#define LL (rt<<1)
#define RR (rt<<1|1)
#define lson l,mid,LL
#define rson mid+1,r,RR
#define pii pair<int,int>
#define pll pair<ll,ll>
#define lb(x) (x&(-x))
void In(){freopen("in.in","r",stdin);}
void Out(){freopen("out.out","w",stdout);}
const int N=2e5+10;
const int M=3e5+10;
const int Mbit=1e6+10;
const ll inf=1e15;
const ll mod=1e9+7;
ll val[N],dp[N],ans;
vector<int>G[N];
void dfs(int u,int fa)
{
    for(int i=0;i<G[u].size();i++){
        int v=G[u][i];
        if(v==fa)continue;
        dfs(v,u);
        val[u]+=val[v];
        if(dp[u]!=-inf)ans=max(ans,dp[u]+dp[v]);
        dp[u]=max(dp[u],dp[v]);
    }
    dp[u]=max(dp[u],val[u]);
}
int main()
{//In();
    int n;
    while(~scanf("%d",&n)){
        for(int i=1;i<=n;i++)scanf("%lld",&val[i]);
        for(int i=1;i<=n;i++)G[i].clear(),dp[i]=-inf;
        ans=-inf;
        for(int i=1;i<n;i++){
            int u,v;scanf("%d%d",&u,&v);
            G[u].PB(v);G[v].PB(u);
        }
        dfs(1,-1);
        if(ans!=-inf)printf("%lld\n",ans);
        else puts("Impossible");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值