作者:
克兰兹
,
2023-01-27 19:40:01
,
所有人可见
,
阅读 7
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1e5 + 10;
int n;
int h[N], e[N * 2], ne[N * 2], idx;
bool st[N];
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] = true;
int size = 0, sum = 1;
for(int i = h[u]; i != -1; i = ne[i])
{
int j = e[i];
if(st[j]) continue;
int s = dfs(j);//返回的是以u为根的子树,除u外的节点数之和
size = max(size, s);//记录连通子图的最大节点数
//sum记录u为根的子树的节点和。包括u,因为要挖掉u
sum += s;
}
//将u为根的子树,挖掉u后最大 连通子图的节点数size,与去掉u为根的这个子树之后,
//剩余节点数比较。样例,u=4时,4的父亲节点,并且其他与之相连的节点总数就是n - sum。
size = max(size, n - sum);
//每一次遍历都比较剩余连通子图的最大节点数,取最小。
ans = min(ans, size);
return sum;
}
int main()
{
scanf("%d", &n);
memset(h, -1 , sizeof h);
for(int i = 0; i < n - 1; i++)
{
int a, b;
scanf("%d%d", &a, &b);
add(a, b), add(b, a);
}
dfs(1);
printf("%d", ans);
return 0;
}