【hihocoder】编程练习赛59第三题树的权重

题目:https://hihocoder.com/contest/offers59/problem/3
其实就是一个树的转移中心的题。
以1为根节点做一遍dfs可以得到1到其他所有点 的距离之和。
求某点到其他点的距离之和的时候可以根据最初的情况转移。
比如设点k是点1的子节点,w[k]=w[1]-cnt[k]+n-cnt[k],其中cnt[k]是k的子树的节点个数(包括k本身)。当根节点由一个点转移到它的子节点k时,k到其子节点的距离均-1,到其他点的距离均+1。

贴代码

#include <bits/stdc++.h>
#define LL long long
using namespace std;
vector<vector<int> >edge;
vector<LL>cnt;
vector<LL>ans;
LL W=0;
int n;

void dfs1(int u,int f,LL d){
    cnt[u]=1;
    W+=d;
    for(int i=0;i<edge[u].size();i++){
        int v=edge[u][i];
        if(v==f)
            continue;
        dfs1(v,u,d+1);
        cnt[u]+=cnt[v];
    }
}
void dfs2(int u,int f,int w){
    ans[u]=w;
    for(int i=0;i<edge[u].size();i++){
        int v=edge[u][i];
        if(v==f)
            continue;
        dfs2(v,u,w-cnt[v]+n-cnt[v]);
    }
}
int main(){

    scanf("%d",&n);
    edge.resize(n+1);
    cnt.resize(n+1);
    ans.resize(n+1);
    int u,v;
    for(int i=1;i<n;i++){
        scanf("%d%d",&u,&v);
        edge[u].push_back(v);
        edge[v].push_back(u);
    }
    dfs1(1,1,0);
    dfs2(1,1,W);
    for(int i=1;i<=n;i++)
        printf("%lld\n",ans[i]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/vermouth_x/article/details/80329440