题目 AcWing 846. 树的重心
邻接表示意图
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 100010, M = N * 2;
int h[N], e[M], ne[M], idx;
int n, ans = M, st[N];
// 创建无向图 a <-> b
void connect(int a,int b)
{
e[idx] = b;
ne[idx] = h[a];
h[a] = idx++;
e[idx] = a;
ne[idx] = h[b];
h[b] = idx++;
}
// 深度优先遍历
int dfs(int u)
{
// 标记该节点已被访问
st[u] = 1;
// sum 存储 以u为根的树 的节点数, 包括u
int sum = 1;
// 存储 删掉某个节点之后,最大的连通子图节点数
int res = 0;
for(int i = h[u]; i != -1; i = ne[i])
{
int j = e[i]; // 取出1个节点
// 判断是否未被访问过
if(!st[j])
{
int s = dfs(j);
res = max(res,s);
sum += s;// 以j为根的树 的节点数
}
}
// 选择u节点为重心,最大的 连通子图节点数
res = max(res, n - sum);
//遍历过的假设重心中,最小的最大联通子图的 节点数
ans = min(res, ans);
return sum;
}
int main()
{
memset(h, -1, sizeof h);
cin >> n;
for(int i = 0;i < n - 1;i++)
{
int a, b;
cin >> a >> b;
connect(a,b);
}
dfs(1);
cout << ans;
return 0;
}