给定一棵无根树,假设它有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
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <vector>
#pragma comment(linker, "/STACK:10240000,10240000")//递归太深,导致爆栈,所以使用扩栈语句
using namespace std;
typedef long long ll;
const int N = 100000 + 5;
vector<int>vv[N];
int num[N],n;
ll dp[N];
int dfs(int u,int pre,int d)
{
int len=vv[u].size();
num[u]=1;
dp[1]+=d;
for(int i=0;i<len;i++) {
if(vv[u][i]==pre) continue;
num[u]+=dfs(vv[u][i],u,d+1);
}
return num[u];
}
void dfs2(int pre,int u)
{
dp[u]=dp[pre]+n-2*num[u];
int len=vv[u].size();
for(int i=0;i<len;i++) {
if(vv[u][i]==pre) continue;
dfs2(u,vv[u][i]);
}
}
int main()
{
int i,j,u,v;
scanf("%d",&n);
for(i=1;i<n;i++) {
scanf("%d%d",&u,&v);
vv[u].push_back(v);
vv[v].push_back(u);
}
dfs(1,0,0);
for(i=0;i<vv[1].size();i++) {
dfs2(1,vv[1][i]);
}
for(i=1;i<=n;i++) printf("%I64d\n",dp[i]);
return 0;
}