51nod 1405 树的距离之和

版权声明:选经典题目,写精品文章. https://blog.csdn.net/nka_kun/article/details/82947277

1405 树的距离之和
基准时间限制:1 秒 空间限制:131072 KB
给定一棵无根树,假设它有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

思路:我们可以先一遍dfs求出每个节点到他的所有子节点的距离和,那么根节点存的就是他到树上每个节点的
距离和,这样根节点的儿子就可以由他转移过来,就可以求出题目要求的答案来.

代码:

#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 2e5+5;

struct node
{
	int u,v,ne;
} e[maxn];

int n;
int head[maxn],len;
int ve[maxn];
ll d[maxn];

void add(int u,int v)
{
	e[len].u = u;
	e[len].v = v;
	e[len].ne = head[u];
	head[u] = len++;
}

void dfs(int x,int p)
{
	ve[x] = 1;
	for(int i = head[x];~i;i = e[i].ne)
	{
		int v = e[i].v;
		if(v == p) continue;
		
		dfs(v,x);
		d[x]+= d[v]+ve[v];
		ve[x]+= ve[v];
	}
	return ;
}

void dfs2(int x,int p)
{
	for(int i = head[x];i!= -1;i = e[i].ne)
	{
		int v = e[i].v;
		if(v == p) continue;
		
		d[v]+= d[x]-d[v]-ve[v]+n-ve[v];
		dfs2(v,x);
	}
	return ;
}

int main()
{
	mem(head,-1);
	cin>>n;
	for(int i = 1,x,y;i< n;i++)
	{
		scanf("%d %d",&x,&y);
		add(x,y);
		add(y,x);
	}
	
	dfs(1,0);
	dfs2(1,0);
	
	for(int i = 1;i<= n;i++)
		printf("%lld\n",d[i]);
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/nka_kun/article/details/82947277
今日推荐