CodeForces - 1092F Tree with Maximum Cost

Posted on   Capterlliar  阅读(30)  评论(0编辑  收藏  举报

题意:给出一棵树,每个结点有一个权值。定义一棵树以ai为根节点的价值为  剩下每个结点到根节点的距离乘权值  之和。求这棵树的最大价值。

解:随便选一个结点为根,从下到上统计当前价值,设son[i]为以i结点为子树根节点,这颗子树价值乘路径长度之和。考虑换根,令当前根ai的一个子节点aj为新的根,ai变成aj的子树。dp[ai]减去aj的贡献,aj原子节点深度减一,贡献减son[aj];剩下的结点深度加一,贡献加sum-son[aj].

代码:

复制代码
#include <bits/stdc++.h>
using namespace std;
#define maxx 200005
#define maxn 25
#define maxm 205
#define ll long long
#define inf 1000000009
#define mod 2520
struct edge{
    int u,v,w,next;
}e[maxx*2];
int head[maxx]={0},cnt=0;
void add(int u,int v){
    e[++cnt].u=u;e[cnt].v=v;e[cnt].next=head[u];head[u]=cnt;
}

int n;
ll ans=0,sum=0;
ll dp[maxx]={0};
ll son[maxx]={0};
ll a[maxx];
void dfs1(int now,int fa,int d){
    dp[now]=d*a[now];
    son[now]=a[now];
    for(int i=head[now];i;i=e[i].next){
        int to=e[i].v;
        if(to==fa) continue;
        dfs1(to,now,d+1);
        dp[now]+=dp[to];
        son[now]+=son[to];
    }
}
void dfs2(int now,int fa){
    ans=max(ans,dp[now]);
    for(int i=head[now];i;i=e[i].next){
        int to=e[i].v;
        if(to==fa) continue;
        dp[now]-=dp[to];
        dp[to]-=son[to];
        dp[to]+=(dp[now]+sum-son[to]);
        dfs2(to,now);
        dp[to]-=(dp[now]+sum-son[to]);
        dp[to]+=son[to];
        dp[now]+=dp[to];
    }
}
signed main() {
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        sum+=a[i];
    }
    for(int i=1;i<=n-1;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        add(x,y);
        add(y,x);
    }
    dfs1(1,0,0);
    dfs2(1,0);
    printf("%lld\n",ans);
    return 0;
}
View Code
复制代码

 

相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示