https://www.patest.cn/contests/pat-a-practise/1021
照抄了http://blog.csdn.net/jtjy568805874/article/details/50805402
里面用到了求树的半径的方法,
1)用任何一个点dfs 找到最深的深度,所有深度最深的node 是半径上的点。
2)再用任意一个半径上的点dfs,找到新的最深的深度,这次遍历后有最深深度的点也是半径上的点。
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define inone(i) scanf("%d",&i)
#define intwo(i,j) scanf("%d%d",&i,&j)
#define loop(i,j,k) for(int i=j;i!=-1;i=k[i])
const int maxn = 1e5 + 10;
int fa[maxn], cnt, n, dep[maxn], maxd, ans[maxn];
int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }
vector<int> G[maxn];
void dfs(int x, int f, int deep)
{
//因为是最小生成树,不会有换,只要不回溯父节点就可以
dep[x] = deep; maxd = max(maxd, deep);
for (int i = 0; i < G[x].size(); i++)
{
if (G[x][i] == f) continue;
dfs(G[x][i], x, deep + 1);
}
}
int main()
{
int x, y;
inone(n);
rep(i, 1, n) fa[i] = i;
cnt = n;
rep(i, 1, n - 1)
{
intwo(x, y);
int fx = find(x), fy = find(y);
if (fx == fy) continue;
fa[fy] = fx;
G[x].push_back(y); G[y].push_back(x);
cnt--;
}
if (cnt != 1) printf("Error: %d components\n", cnt);
else {
cnt = 0;
dfs(1, 1, 0);
rep(i, 1, n) if (dep[i] == maxd) ans[cnt++] = i;
dfs(ans[0], ans[0], 0);
rep(i, 1, n) if (dep[i] == maxd) ans[cnt++] = i;
sort(ans, ans + cnt);
cnt = unique(ans, ans + cnt) - ans;
rep(i, 0, cnt - 1) printf("%d\n", ans[i]);
}
return 0;
}