CF 743D

题目:

给出一棵树,求大两棵子树权重和。

题解:

我今天心情本来是烦躁的,想刷两题水题解闷……结果卡题了!!!我现在的心情是暴躁的!!

我们扯一会儿题解。

首先dfs一遍把每个点的权重算出来肯定能想到。

然后开始考虑如何维护“两个”子树的最大值。

后来发现自己傻逼了只需要维护一个子树的最大值就行了。

dp[i]表示i号节点的最大子树权重和。

j表示i的孩子。

dp[i]=max(所有dp[j],dp[i])

然后WA了。

发现判断叶子节点的时候没有特判根节点。

然后WA了。

发现是没有设long long。

然后WA了。

发现是最大值初始化不够小。

然后过了。

想摔桌子,砸墙壁。。

#include<iostream>
#include<vector>
using namespace std;

const long long INF=1e18+1;
long long n;
long long arr[201000];
long long weight[201000];
long long dp[201000];
vector<long long> vec[201000];
long long ans=-INF;

void getweight(long long fa,long long x){
    if(vec[x].size()==1&&x!=1){
        weight[x]=arr[x];
        return ;
    }
    long long all=arr[x];
    for(long long i=0;i<vec[x].size();i++){
        long long to=vec[x][i];
        if(to==fa) continue;
        getweight(x,to);
        all+=weight[to];
    }
    weight[x]=all;
}

void getdp(long long fa,long long x){
    if(vec[x].size()==1&&x!=1){
        dp[x]=weight[x];
        return ;
    }
    dp[x]=weight[x];
    long long bit=0;
    long long max1=-INF;
    long long max2=-INF;
    for(long long i=0;i<vec[x].size();i++){
        long long to=vec[x][i];
        if(to==fa) continue;
        getdp(x,to);
        if(dp[to]>max1){
            max2=max1;
            max1=dp[to];
        }
        else if(dp[to]>max2){
            max2=dp[to];
        }
        dp[x]=max(dp[x],dp[to]);
    }
    if(max1!=-INF&&max2!=-INF&&max1+max2>ans){
        ans=max1+max2;
    }
}

int main(){
    cin>>n;
    for(long long i=1;i<=n;i++){
        cin>>arr[i];
    }
    for(long long i=0;i<n-1;i++){
        long long a,b;
        cin>>a>>b;
        vec[a].push_back(b);
        vec[b].push_back(a);
    }
    getweight(0,1);
    getdp(0,1);
    if(ans==-INF) cout<<"Impossible"<<endl;
    else cout<<ans<<endl;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值