#include <bits/stdc++.h>
using namespace std;
int n;
const int N = 1e5+10;
vector<vector<int>> tree(N);
bool vis[N];
int ans= 0x3f3f3f3f;
//图的深搜可以看成多叉树的前序遍历,vis是其关键。
//我们可以用树遍历时的回溯来得到以u为根的子树的节点个数sum,这样我们只需要遍历一遍就可以得到所有u的子树的连通块,和剩下的那个n-sum连通块
//不需要一个节点一个节点分别做起点去再遍历各个连通块,从n^2变为n
//一次遍历就可以得到结果,有点像差分呀
//以u为根的子树的点的个数
int dfs(int u)
{
vis[u]= true;
int sum=1, tmp=0;//tmp是连通块最大值
//遍历所有u的子树,不含根
for(int i= 0;i<tree[u].size(); i++)
{
if(!vis[tree[u][i]])
{
int ret= dfs(tree[u][i]);
tmp= max(ret,tmp);
sum+=ret;
}
}
tmp= max(tmp,n-sum);
ans=min(ans, tmp);
return sum;
}
int main()
{
cin>>n;
for(int i=0; i<n-1; i++)
{
int a,b;
cin>>a >>b;
tree[a].push_back(b),tree[b].push_back(a);
}
dfs(1);
cout<<ans;
return 0;
}
acwing树的重心
最新推荐文章于 2025-06-12 00:21:00 发布