Yuuki and a problem
题目连接:https://nanti.jisuanke.com/t/42552
题意
有一棵树,以1号节点为根,求以每个节点为根的子树的重心。
题解:
题目其实给的一个公式,可以发现就是树的重心的第一个式子。而且题目输出要求说如果有两个中间需要空格分隔,就已经暗示的很明显了是求树的重心。求树的重心可以利用树的重心的性质来求。
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<ctype.h>
#include<cstring>
#include<vector>
#include<queue>
#include<map>
#include<iostream>
#include<iterator>
#define dbg(x) cout<<#x<<" = "<<x<<endl;
#define INF 0x3f3f3f3f
#define eps 1e-8
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
const int maxn = 200100;
const int mod = 998244353;
int dp[maxn], sum[maxn], fa[maxn], mx[maxn];
vector<int> g[maxn], ans[maxn];
void dfs(int u);
int main()
{
int n, i, j, k;
scanf("%d", &n);
for(i=1;i<n;i++)
{
scanf("%d %d", &j, &k);
g[j].push_back(k);
g[k].push_back(j);
}
dfs(1);
for(i=1;i<=n;i++)
{
if(ans[i].size() == 1)
printf("%d\n", ans[i][0]);
else if(ans[i][0] < ans[i][1])
printf("%d %d\n", ans[i][0], ans[i][1]);
else
printf("%d %d\n", ans[i][1], ans[i][0]);
}
return 0;
}
void dfs(int u)
{
sum[u] = 1;
dp[u] = u;
mx[u] = 0;
for(int i=0;i<g[u].size();i++)
if(g[u][i] != fa[u]){
fa[g[u][i]] = u;
dfs(g[u][i]);
mx[u] = max(mx[u], sum[i]);
sum[u] += sum[g[u][i]];
}
for(int i=0;i<g[u].size();i++)
{
if(g[u][i]!=fa[u] && sum[g[u][i]]*2 >= sum[u])
dp[u] = dp[g[u][i]];
}
while((sum[u]-sum[dp[u]])*2 > sum[u])
dp[u] = fa[dp[u]];
ans[u].push_back(dp[u]);
if(dp[u]!=u && sum[dp[u]]*2 == sum[u])
ans[u].push_back(fa[dp[u]]);
}