题意:求树的重心的编号以及重心删除后得到的最大子树的节点个数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; }