解法一:连通分支+DFS

第一遍DFS求出连通分支数量,并找出深度最大的结点集;第二次从中随机取出一点作为遍历起点,找出深度最大的结点集。两次结果的并集即为最终答案。

  1. import java.io.*;
  2. import java.util.*;
  3. public class Main {
  4. private static boolean[] isVisited;
  5. private static int maxDepth;
  6. private static List<Integer> deepest;
  7. private static List<List<Integer>> map;
  8. public static void main(String[] args) throws IOException {
  9. StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
  10. PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
  11. in.nextToken();
  12. int N = (int) in.nval;
  13. map = new ArrayList<>(N);
  14. for (int i = 0; i <= N; ++i) {
  15. map.add(new ArrayList<>());
  16. }
  17. for (int i = 1, u, v; i < N; ++i) {
  18. in.nextToken();
  19. u = (int) in.nval;
  20. in.nextToken();
  21. v = (int) in.nval;
  22. map.get(u).add(v);
  23. map.get(v).add(u);
  24. }
  25. isVisited = new boolean[N + 1];
  26. maxDepth = 0;
  27. deepest = new ArrayList<>();
  28. int k = 0;
  29. for (int i = 1; i <= N; ++i) {
  30. if (!isVisited[i]) {
  31. dfs(i, 0);
  32. ++k;
  33. }
  34. }
  35. if (k > 1) {
  36. out.println("Error: " + k + " components");
  37. out.flush();
  38. return;
  39. }
  40. SortedSet<Integer> ans = new TreeSet<>(deepest);
  41. int src = deepest.get(0);
  42. deepest.clear();
  43. Arrays.fill(isVisited, false);
  44. dfs(src, 0);
  45. ans.addAll(deepest);
  46. for (int i : ans) {
  47. out.println(i);
  48. }
  49. out.flush();
  50. }
  51. private static void dfs(int index, int deep) {
  52. isVisited[index] = true;
  53. if (deep > maxDepth) {
  54. maxDepth = deep;
  55. deepest.clear();
  56. deepest.add(index);
  57. } else if (deep == maxDepth) {
  58. deepest.add(index);
  59. }
  60. for (int i : map.get(index)) {
  61. if (!isVisited[i]) {
  62. dfs(i, deep + 1);
  63. }
  64. }
  65. }
  66. }