AcWing 846. (DFS-树的遍历)树的重心
原题链接
简单
作者:
Avetre
,
2025-04-09 17:32:42
· 湖北
,
所有人可见
,
阅读 2
分析:
在DFS遍历树的过程中,记录以每个节点为根节点的子树中含有的节点数目
并返回,同时计算出删除节点u后,划分出的联通块的节点数
,比较出最大节点数的最小值并记录
联通块的划分:

注意:
1.将树存储为无向图
的形式,则无论从哪个节点开始遍历,都能遍历完所有节点
;若想存储为有向图
的形式,则必须知道树的根节点以及各边的指向
,否则无法遍历到树的所有节点
2.不存在重复边
的n个点
组成的无向图
,至多
构成2*n条边
3.h[]数组
要初始化为全-1
,表示所有点都未构成边
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
bool st[N];
int h[N],e[2*N],ne[2*N],idx;
int n,a,b;
int ans = N;
void add(int a,int b)
{
e[idx] = b;ne[idx] = h[a];h[a] = idx++;
}
int dfs(int u)
{
st[u] = 1;
int sum = 1;
int res = 0;
for(int i = h[u];i != -1;i = ne[i])
{
int j = e[i];
if(!st[j])
{
int s = dfs(j);
sum += s;
res = max(res,s);
}
}
res = max(res,n - sum);
ans = min(res,ans);
return sum;
}
int main()
{
cin >> n;
memset(h,-1,sizeof h);
for(int i = 1;i < n;i ++)
{
cin >> a >> b;
add(a,b);add(b,a);
}
dfs(1);
cout << ans << endl;
return 0;
}