树的重心
树的重心:树的某个节点,当去掉该节点后,树的各个子树中,节点数最多的子树其节点数达到最小值。树可能存在多个重心。
说人话:删掉重心后最大的子树的节点数最小
树的重心对新人一点也不友好。
题意:先输入t 代表测试数据个数,然后每个用例第一行一个n接下来n-1行代表各个相连的节点,每个节点都会出现。
这题主要考虑用dfs计算每个节点的子节点的连通块数量,然后比较出最小的那个,需要注意的一点是,该节点的父节点的节点数=总结点-该节点子节点节点数之和,上代码:
#include <iostream>
#include <string.h>
#include <vector>
using namespace std;
#define INF 1e8
#define N 2005
int i,j,k,n,t,a,b;
int ans1,ans2;
int d[N];
vector<int>G[N];
void dfs(int u,int p)
{
int i,v;
d[u]=1;
int mmax=0;
for(i=0;i<G[u].size();i++)
{
v=G[u][i];
if(v!=p)
{
dfs(v,u);
mmax=max(mmax,d[v]);
d[u]+=d[v];
}
}
mmax=max(mmax,n-d[u]);
if(ans1>mmax)
{
ans1=mmax;
ans2=u;
}
}
int main()
{
cin>>t;
while(t--)
{
cin>>n;
for(i=0;i<=n;i++)
{
G[i].clear();
}
for(i=0;i<n-1;i++)
{
cin>>a>>b;
G[a].push_back(b);
G[b].push_back(a);
}
ans1=INF;
dfs(1,0);
cout<<ans2<<' '<<ans1;
}
return 0;
}
第二个版本>>>只有dfs不一样:
#include <iostream>
#include <string.h>
#include <vector>
using namespace std;
#define INF 1e8
#define N 2005
int i,j,k,n,t,a,b;
int ans1,ans2;
vector<int>G[N];
int dfs(int u,int p)
{
int i,v;
int mmax=0,sum=0;
for(i=0;i<G[u].size();i++)
{
v=G[u][i];
if(v!=p)
{
int t=dfs(v,u);
mmax=max(mmax,t);
sum+=t;
}
}
mmax=max(mmax,n-sum-1);
if(ans1>mmax)
{
ans1=mmax;
ans2=u;
}
return sum+1;
}
int main()
{
cin>>t;
while(t--)
{
cin>>n;
for(i=0;i<=n;i++)
{
G[i].clear();
}
for(i=0;i<n-1;i++)
{
cin>>a>>b;
G[a].push_back(b);
G[b].push_back(a);
}
ans1=INF;
dfs(1,0);
cout<<ans2<<' '<<ans1;
}
return 0;
}