解法一:连通分支+DFS
第一遍DFS求出连通分支数量,并找出深度最大的结点集;第二次从中随机取出一点作为遍历起点,找出深度最大的结点集。两次结果的并集即为最终答案。
import java.io.*;
import java.util.*;
public class Main {
private static boolean[] isVisited;
private static int maxDepth;
private static List<Integer> deepest;
private static List<List<Integer>> map;
public static void main(String[] args) throws IOException {
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
in.nextToken();
int N = (int) in.nval;
map = new ArrayList<>(N);
for (int i = 0; i <= N; ++i) {
map.add(new ArrayList<>());
}
for (int i = 1, u, v; i < N; ++i) {
in.nextToken();
u = (int) in.nval;
in.nextToken();
v = (int) in.nval;
map.get(u).add(v);
map.get(v).add(u);
}
isVisited = new boolean[N + 1];
maxDepth = 0;
deepest = new ArrayList<>();
int k = 0;
for (int i = 1; i <= N; ++i) {
if (!isVisited[i]) {
dfs(i, 0);
++k;
}
}
if (k > 1) {
out.println("Error: " + k + " components");
out.flush();
return;
}
SortedSet<Integer> ans = new TreeSet<>(deepest);
int src = deepest.get(0);
deepest.clear();
Arrays.fill(isVisited, false);
dfs(src, 0);
ans.addAll(deepest);
for (int i : ans) {
out.println(i);
}
out.flush();
}
private static void dfs(int index, int deep) {
isVisited[index] = true;
if (deep > maxDepth) {
maxDepth = deep;
deepest.clear();
deepest.add(index);
} else if (deep == maxDepth) {
deepest.add(index);
}
for (int i : map.get(index)) {
if (!isVisited[i]) {
dfs(i, deep + 1);
}
}
}
}