题目链接:https://vjudge.net/problem/POJ-1655
这个就是找树的重心,树的重心就是树里面找一个点,使得以这个点为树根的所有的子树中最大的子树节点数最小。题目应该讲的比较清楚了,直接看代码吧:
#include<iostream> #include<cstring> #include<algorithm> #include<queue> #include<map> #include<stack> #include<cmath> #include<vector> #include<set> #include<cstdio> #include<string> #include<deque> using namespace std; typedef long long LL; #define eps 1e-8 #define INF 0x3f3f3f3f #define maxn 200005 struct node{ int v,next; }edge[maxn*2]; int n,m,k,t,cnt; int vis[maxn],head[maxn],dis[maxn];//dis[i]记录以点i为树根的树,它子树里面包含点最多的值 void init(){ memset(head,-1,sizeof(head)); memset(vis,0,sizeof(vis)); memset(dis,0,sizeof(dis)); cnt=0; } void add(int u,int v){ edge[++cnt].v=v; edge[cnt].next=head[u]; head[u]=cnt; } int DFS(int u){//搜索以点u为根节点的树下面的所有节点数量(包括自己)并返回,同时求出dis[u] vis[u]=true; int sum_son=0;//一开始儿子节点总数为0 for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].v; if(!vis[v]){ int s=DFS(v);// sum_son+=s;//加上以v为根节点的子树的数量 dis[u]=max(dis[u],s);//求最大值 } } dis[u]=max(dis[u],n-sum_son-1);//不在这棵树下面的所有非子树节点的数量,总数-儿子节点数-自己 return sum_son+1; } int main() { scanf("%d",&t); while(t--){ scanf("%d",&n); init(); int u,v,w; for(int i=1;i<n;i++){ scanf("%d%d",&u,&v); add(u,v); add(v,u); } DFS(1); int ans,max1=INF; for(int i=1;i<=n;i++){ if(dis[i]<max1||dis[i]==max1&&i<ans){ ans=i; max1=dis[i]; } } printf("%d %d ",ans,max1); } return 0; }