题意:求树的重心的编号以及重心删除后得到的最大子树的节点个数size,如果size相同就选取编号最小的.
思路:随便选一个点把无根图转化成有根图,dfs一遍即可dp出答案
//1348K 125MS C++ 1127B
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
int n;
const int N= 20020;
struct Edge
{
int v;
Edge(int _v=0) : v(_v) {};
};
vector<Edge>es[N];
int sumson[N];
int ans,cur;
void dfs(int u,int pa)
{
int tmp=-1;
for(int i=0;i<es[u].size();i++)
{
int v=es[u][i].v;
if(v==pa) continue;
dfs(v,u);
sumson[u]+=(sumson[v]+1);
tmp=max(tmp,sumson[v]+1);
}
tmp=max(tmp,n-sumson[u]-1);
if(tmp<ans||(tmp==ans&&u<cur))
{
ans=tmp;
cur=u;
}
}
void ini()
{
for(int i=1;i<=n;i++)
es[i].clear();
memset(sumson,0,sizeof(sumson));
ans=0x3f3f3f3f;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
ini();
int u,v;
for(int i=1;i<n;i++)
{
scanf("%d%d",&u,&v);
es[u].push_back(Edge(v));
es[v].push_back(Edge(u));
}
dfs(1,0);
printf("%d %d\n",cur,ans);
}
return 0;
}