题目传送门https://vjudge.net/problem/CSES-1133#author=GPT_zh
解题思路
先求出根节点 1 号点的答案,和每个点的子树大小
设 为
号点的答案。
对于每一个点 和它的根节点
,
和
的关系是什么?
聪明的你也许很快就能想到……
从 到
,一共有
个点的距离减少了 1,有
个点的距离加了 1.
所以,可以轻松得到:
。
这样就做完了……
代码
记得开 long long……
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n;
vector<int> g[200001];
int sz[200001],f[200001],sum;
int ans[200001];
void dfs1(int x,int fa)
{
sz[x]=1;
for(auto y:g[x])
{
if(y!=fa)
{
f[y]=f[x]+1;
dfs1(y,x);
sz[x]+=sz[y];
}
}
}
void dfs2(int x,int fa)
{
for(auto y:g[x])
{
if(y!=fa)
{
ans[y]=ans[x]-sz[y]+(n-sz[y]);
dfs2(y,x);
}
}
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n;
int x,y;
for(int i=1;i<n;i++)
{
cin>>x>>y;
g[x].push_back(y);
g[y].push_back(x);
}
dfs1(1,1);
for(int i=1;i<=n;i++)
sum+=f[i];
ans[1]=sum;
dfs2(1,1);
for(int i=1;i<=n;i++)
cout<<ans[i]<<" ";
return 0;
}