1405 树的距离之和

1405 树的距离之和
《1405 树的距离之和》 基准时间限制:1 秒 空间限制:131072 KB 分值: 40
难度:4级算法题

《1405 树的距离之和》 收藏

《1405 树的距离之和》 取消关注 给定一棵无根树,假设它有n个节点,节点编号从1到n, 求任意两点之间的距离(最短路径)之和。 Input

第一行包含一个正整数n (n <= 100000),表示节点个数。
后面(n - 1)行,每行两个整数表示树的边。

Output

每行一个整数,第i(i = 1,2,...n)行表示所有节点到第i个点的距离之和。

Input示例

4
1 2
3 2
4 2

Output示例

5
3
5
5
/* ***********************************************
Author        :xdlove
Created Time  :2016年05月17日 星期二 07时12分25秒
File Name     :2016_05_17_51nod_1405.cpp
************************************************ */

#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <memory.h>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>

using namespace std;
const int N = 1e5 + 10;
long long son[N],val[N];
long long ans[N];
struct Edge
{
    int v,next;
}edge[N << 1];
int head[N],tot;
int n;

void init()
{
    tot = 0;
    memset(head,-1,sizeof head);
}

void addedge(int u,int v)
{
    edge[tot].v = v;
    edge[tot].next = head[u];
    head[u] = tot++;
}

void dfs(int u,int pre)
{
    son[u] = 1;
    val[u] = 0;
    for(int i = head[u]; i != -1; i = edge[i].next)
    {
        int v = edge[i].v;
        if(v != pre)
        {
            dfs(v,u);
            son[u] += son[v];
            val[u] += son[v] + val[v];
        }
    }
}

void dfsAgain(int u,int pre)
{
    ans[u] = val[u];
    for(int &i = head[u]; i != -1; i = edge[i].next)
    {
        int v = edge[i].v;
        if(v != pre)
        {
            long long tp = val[u] - val[v] - son[v];
            val[v] += n - son[v] + tp;
            dfsAgain(v,u);
        }
    }
}

void solve()
{
    init();
    cin >> n;
    for(int i = 1; i <= n - 1; ++i)
    {
        int u,v;
        scanf("%d %d",&u,&v);
        addedge(u,v);
        addedge(v,u);
    }
    dfs(1,-1);
    dfsAgain(1,-1);
    for(int i = 1; i <= n; ++i)
        printf("%lld\n",ans[i]);
}

int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    solve(); 
    return 0;
}
点赞