解题思路:选择一个节点作为根,设dp[i]表示以i为根的树的总节点个数,dp[i]=满足j为其子节点的的d[j]之和再加1(根节点)。只需在dfs过程中找到最大的子树节点,并与其上方的节点数做比较,就可以找出树的重心了。
题目大意:对于一棵无根树,找到一个点使得树以该点为根的有根树,最大子树(选择该节点后其子树的最大节点)的节点数最小。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define inf 1<<30
int n,dp[101],node,minans;
vector<int> edge[101];
int dfs(int m,int fa)
{
int maxnode=0;
for(int i=0;i<edge[m].size();i++)
{
int tmp=edge[m][i];
if(tmp!=fa)
{
dp[m]+=dfs(tmp,m);
maxnode=max(maxnode,dp[tmp]); //得到最大子树节点数
}
}
maxnode=max(maxnode,n-dp[m]); //再与上方的节点数做比较
if(maxnode<minans)
{
minans=maxnode;
node=m;
}
return dp[m];
}
int main()
{
while(cin>>n)
{
for(int i=1;i<=n;i++) edge[i].clear();
int a,b;
for(int i=1;i<=n-1;i++)
{
cin>>a>>b;
edge[a].push_back(b);
edge[b].push_back(a);
}
for(int i=1;i<=n;i++) //初始化都是1,即根节点本身
{
dp[i]=1;
}
minans=inf;
dfs(1,-1);
cout<<minans<<" "<<node<<endl;
}
return 0;
}