思路:求平衡点,实际就是求一棵树的重心,我们只需要从上往下递归求出每一颗树的孩子的子树大小,模拟一个换根的过程,先把1当做根,记录下每一个节点的子树大小,在模拟换根的过程中,假设x为根,那么只需要记录一下它所有儿子的子树和以及n-其子树和中最大的值,然后取一个最小的最大值即可
#include <iostream>
#include<stdio.h>
#include<string>
#include<string.h>
#include<map>
#include<queue>
#include<deque>
#include<vector>
#include<algorithm>
#include<set>
using namespace std;
typedef long long ll;
typedef pair<int,ll>P;
const int maxn=2e4+10;
const int maxe=4e4+100;
const int inf=1e9+7;
const int mod=1e9+7;
inline int readii(){
int sgn = 1; int cnt = 0;char ch = getchar();
while (ch < '0' || ch > '9') {if(ch == '-')sgn = -sgn;ch = getchar();}
while ('0' <= ch && ch <= '9') {cnt = cnt*10 + (ch-'0');ch = getchar();}
return sgn*cnt;
}
inline int readll(){
int sgn = 1; int cnt = 0;char ch = getchar();
while (ch < '0' || ch > '9') {if(ch == '-')sgn = -sgn;ch = getchar();}
while ('0' <= ch && ch <= '9') {cnt = cnt*10 + (ch-'0');ch = getchar();}
return sgn*cnt;
}
int t,n;
struct edge
{
int to;
int val;
int nxt;
}e[maxe];
int head[maxn],vis[maxn];
int tot_size,siz[maxn];
int tmpG,maxsz,cnt;
void Init(int x,int y)
{
for(int i=x;i<=y;i++) head[i]=-1,vis[i]=0;
cnt=0;tot_size=n;tmpG=0;maxsz=inf;
}
void Addedge(int u,int v,int val)
{
e[cnt].to=v;
e[cnt].val=val;
e[cnt].nxt=head[u];
head[u]=cnt++;
}
void GetG(int x)
{
siz[x]=1;
vis[x]=1;
int x_max_size=0;
for(int i=head[x];i!=-1;i=e[i].nxt)
{
int v=e[i].to;
if(vis[v]) continue;
GetG(v);
siz[x]+=siz[v];
x_max_size=max(x_max_size,siz[v]);
}
x_max_size=max(x_max_size,tot_size-siz[x]);
if(x_max_size<maxsz)
{
tmpG=x;
maxsz=x_max_size;
}
return ;
}
int main()
{
while(~scanf("%d",&n))
{
Init(1,n);
int u,v;
for(int i=1;i<n;i++)
{
u=readii();v=readii();
Addedge(u,v,0);
Addedge(v,u,0);
}
GetG(1);
printf("%d %d\n",tmpG,maxsz);
}
return 0;
}

京公网安备 11010502036488号