Codeforces 743D Chloe and pleasant prizes

首先题意很清楚了,就是找两颗不想关的子树,使其权值和最大。


这是一道树形dp,也是我做的第一道树形dp,非常有纪念意义,所以在这里写一下。

写法非常智障,说明自己姿势水平还是太低。

先贴代码。

#include<bits/stdc++.h>
using namespace std;
const int maxn=200000+10;
const long long INF=10000000000000000;//这里要设大一点因为题目数据很大
long long ans,max1,max2;
int n;
vector<int> G[maxn],B[maxn];//B用来临时存储,G中存的树要求是有序的,即一条边只加一次
long long value[maxn],sum[maxn],dp[maxn];
void dfs1(int x)//calculate the sum of the subtree of x,计算每个节点子树的权值和sum
{
    sum[x]=value[x];
    for(auto it:G[x])
    {
        dfs1(it);
        sum[x]+=sum[it];
    }
}
void dfs2(int x)//calculate the largest sum of sub-trees of x,计算每个节点i的后代(包括i)中,sum最大的,记作dp【i】
{
    dp[x]=sum[x];
    for(auto it:G[x])
    {
        dfs2(it);
        dp[x]=max(dp[x],dp[it]);
    }
}
void doit(long long &max1,long long &max2,long long x)//update max1 and max2,max1为最大,max2为次大,x为新接受的元素
{
    if(x<=max2)
        return ;
    if(x>=max1)
    {
        max2=max1;
        max1=x;
        return ;
    }
    {
        max2=x;
        return ;
    }
}
void dfs(int x,int fa)//瞎几把遍历,生成G
{
    for(auto i:B[x])
    {
        if(i==fa)
            continue;
        G[x].push_back(i);
        dfs(i,x);
    }
}
int main(void)
{
    int u,v;
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>value[i];
    for(int i=1;i<n;i++)
    {
        cin>>u>>v;
        B[u].push_back(v);
        B[v].push_back(u);
    }//读入,暂时存着,因为给的节点关系是无序的,需要经过预处理,使得其有序
    dfs(1,-1);//to ensure the father and child relation:G[u]=v then v is child of u
    dfs1(1);
    dfs2(1);
    ans=-INF;
    for(int i=1;i<=n;i++)
    {
        if(G[i].size()>=2)
        {
            max1=max(dp[G[i][0]],dp[G[i][1]]);//the largest
            max2=min(dp[G[i][0]],dp[G[i][1]]);//the second largest
            for(int j=2;j<G[i].size();j++)
            {
                doit(max1,max2,dp[G[i][j]]);
            }
            ans=max(ans,max1+max2);
        }
        else
            continue;
    }
    if(ans==-INF)
        cout<<"Impossible";
    else
        cout<<ans;
    return 0;
}
这道题我的时间控制的不是很好,因为加了一个预处理,把树按照标准形式存到了G里。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值