题目原文
题意:
求数的重心,以及最重的子树的节点数。
树的重心:去掉树上某个点后,若使剩下的子树中节点数最大的子树的节点数最小则该点为树的重心
代码:
/* 使用前初始化G
* 时间复杂度O(n)
*/
vector<int> G[20005];
int n;
int dp[20005],w[20005];
int dfs(int u,int f)
{
if(dp[u]!=-1) return dp[u];
int res=0,sum=0;
for(int i=0;i<G[u].size();i++)
{
int to=G[u][i];
if(to==f) continue;
res=max(res,dfs(to,u));
sum+=dfs(to,u);
}
res=max(n-sum-1,res);
w[u]=res;
return dp[u]=sum+1;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(dp,-1,sizeof dp);
for(int i=0;i<20005;i++) G[i].clear();
scanf("%d",&n);
for(int i=1;i<n;i++)
{
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
dfs(1,-1);
int Min=INF,Mini;
for(int i=1;i<=n;i++)
{
if(w[i]<Min) Min=w[i],Mini=i;
}
printf("%d %d\n",Mini,Min);
}
return 0;
}