**2190 - 树的重心
** 来源:东方博宜oj oj.czos.cn
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,x,y,k;
int r[N];
int fa[N],pre[N],si[N]; // si[]存储每个节点对应的子树最大值
struct node
{
int from,to,next;
}a[N*2];
void add(int u,int v)
{
++k;
a[k].from=u;
a[k].to=v;
a[k].next=pre[u];
pre[u]=k;
}
// 求出每个节点对应的子树大小和父子关系
int dfs(int x,int f)
{
si[x]=1; // 初始化每个节点si[]为1
fa[x]=f;
for(int i=pre[x];i!=0;i=a[i].next)
{
if(a[i].to!=f) si[x]=si[x]+dfs(a[i].to,x);
}
return si[x];
}
int main()
{
cin>>n;
for(int i=1;i<=n-1;i++)
{
cin>>x>>y;
add(x,y);
add(y,x);
}
// 以任意一个点为根,求出每个节点对应的子树最大值
dfs(1,0);
//求出以每个节点为根,对应的最大子树的大小
//以及最大子树的最小数
int minn=INT_MAX;
for(int i=1;i<=n;i++)
{
r[i]=n-si[i];
//循环i号节点对应的子树
for(int j=pre[i];j!=0;j=a[j].next)
{
if(fa[a[j].to]==i) //保证去到的那个节点父节点就是i,则这个节点才是真正的子树
{
r[i]=max(r[i],si[a[j].to]);
}
}
minn=min(minn,r[i]);
}
for(int i=1;i<=n;i++)
{
if(r[i]==minn) cout<< i<< " ";
}
return 0;
}
2190 - 树的重心
于 2023-02-16 23:03:38 首次发布