思路:求平衡点,实际就是求一棵树的重心,我们只需要从上往下递归求出每一颗树的孩子的子树大小,模拟一个换根的过程,先把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;
}