解法一:连通分支+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);}}}}
