解法一:Kruskal算法

思路

  1. import java.io.BufferedReader;
  2. import java.io.IOException;
  3. import java.io.InputStreamReader;
  4. import java.util.Arrays;
  5. import java.util.Comparator;
  6. public class Main {
  7. public static void main(String[] args) throws IOException {
  8. BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
  9. String[] strs = reader.readLine().split(" ");
  10. final int n = Integer.parseInt(strs[0]);
  11. final int m = Integer.parseInt(strs[1]);
  12. Point[] points = new Point[n + 1];
  13. for (int i = 1; i <= n; ++i) {
  14. points[i] = new Point(i);
  15. }
  16. Line[] lines = new Line[m];
  17. Comparator<Line> lineComparator = new Comparator<Line>() {
  18. @Override
  19. public int compare(Line o1, Line o2) {
  20. return Integer.compare(o1.val, o2.val);
  21. }
  22. };
  23. for (int i = 0; i < m; ++i) {
  24. strs = reader.readLine().split(" ");
  25. lines[i] = new Line(Integer.parseInt(strs[0]), Integer.parseInt(strs[1]), Integer.parseInt(strs[2]));
  26. }
  27. Arrays.sort(lines, lineComparator);
  28. int[] ans = new int[n - 1];
  29. int index = 0;
  30. for (int i = 0, u, v; i < m; ++i) {
  31. u = lines[i].u;
  32. v = lines[i].v;
  33. if (union(points[u], points[v])) {
  34. ans[index++] = i;
  35. if (index == n - 1) {
  36. break;
  37. }
  38. }
  39. }
  40. if (index < n - 1) {
  41. System.out.println(-1);
  42. } else {
  43. int sum = 0;
  44. for (int i : ans) {
  45. // System.out.println(lines[i]);
  46. sum += lines[i].val;
  47. }
  48. System.out.println(sum);
  49. }
  50. }
  51. private static boolean union(Point u, Point v) {
  52. Point uMaster = u.getOrigin();
  53. Point vMaster = v.getOrigin();
  54. if (uMaster == vMaster) {
  55. return false;
  56. }
  57. uMaster.master = vMaster;
  58. return true;
  59. }
  60. }
  61. class Point {
  62. int id;
  63. // 标识是否在同一棵树上
  64. Point master;
  65. public Point getOrigin() {
  66. master = _getOrigin(this);
  67. return master;
  68. }
  69. private Point _getOrigin(Point p) {
  70. if (p != p.master) {
  71. p.master = _getOrigin(p.master);
  72. }
  73. return p.master;
  74. }
  75. public Point(int id) {
  76. this.id = id;
  77. master = this;
  78. }
  79. }
  80. class Line {
  81. int u;
  82. int v;
  83. int val;
  84. public Line(int u, int v, int val) {
  85. this.u = u;
  86. this.v = v;
  87. this.val = val;
  88. }
  89. @Override
  90. public String toString() {
  91. return "Line{" +
  92. "u=" + u +
  93. ", v=" + v +
  94. ", val=" + val +
  95. '}';
  96. }
  97. }

解法二:Prime算法

  1. import java.io.BufferedReader;
  2. import java.io.IOException;
  3. import java.io.InputStreamReader;
  4. import java.util.*;
  5. public class Main {
  6. public static void main(String[] args) throws IOException {
  7. BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
  8. String[] strs = reader.readLine().split(" ");
  9. final int n = Integer.parseInt(strs[0]);
  10. final int m = Integer.parseInt(strs[1]);
  11. Point[] points = new Point[n + 1];
  12. for (int i = 1; i <= n; ++i) {
  13. points[i] = new Point(i);
  14. }
  15. int[][] graph = new int[n + 1][n + 1];
  16. for (int i = 1; i <= n; ++i) {
  17. Arrays.fill(graph[i], Integer.MAX_VALUE);
  18. graph[i][i] = 0;
  19. }
  20. for (int i = 0, u, v, val; i < m; ++i) {
  21. strs = reader.readLine().split(" ");
  22. u = Integer.parseInt(strs[0]);
  23. v = Integer.parseInt(strs[1]);
  24. val = Integer.parseInt(strs[2]);
  25. graph[u][v] = val;
  26. graph[v][u] = val;
  27. }
  28. for (int i = 1; i <= n; ++i) {
  29. points[i].dis = graph[i][1];
  30. }
  31. List<Point> undoList = new LinkedList<>();
  32. for (int i = 2; i <= n; ++i) {
  33. undoList.add(points[i]);
  34. }
  35. int[] ans = new int[n - 1];
  36. int index = 0;
  37. for (int i = 0; i < n - 1; ++i) {
  38. Point min = new Point(0);
  39. min.dis = Integer.MAX_VALUE;
  40. for (Point p : undoList) {
  41. if (p.dis < min.dis) {
  42. min = p;
  43. }
  44. }
  45. if (min.dis == Integer.MAX_VALUE) {
  46. System.out.println(-1);
  47. return;
  48. }
  49. ans[index++] = min.dis;
  50. int minIndex = min.id;
  51. for (Iterator<Point> iter = undoList.iterator(); iter.hasNext(); ) {
  52. Point tmp = iter.next();
  53. if (tmp.equals(min)) {
  54. iter.remove();
  55. } else {
  56. tmp.dis = Math.min(tmp.dis, graph[minIndex][tmp.id]);
  57. }
  58. }
  59. }
  60. int sum = 0;
  61. for (int i : ans) {
  62. sum += i;
  63. }
  64. System.out.println(sum);
  65. }
  66. }
  67. class Point {
  68. int id;
  69. int dis;
  70. public Point(int id) {
  71. this.id = id;
  72. dis = 0;
  73. }
  74. @Override
  75. public boolean equals(Object o) {
  76. if (this == o) return true;
  77. if (o == null || getClass() != o.getClass()) return false;
  78. Point point = (Point) o;
  79. return id == point.id;
  80. }
  81. }

解法三:Prime算法+堆优化

  1. import java.io.BufferedReader;
  2. import java.io.IOException;
  3. import java.io.InputStreamReader;
  4. import java.util.*;
  5. public class Main {
  6. public static void main(String[] args) throws IOException {
  7. BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
  8. String[] strs = reader.readLine().split(" ");
  9. final int n = Integer.parseInt(strs[0]);
  10. final int m = Integer.parseInt(strs[1]);
  11. Point[] points = new Point[n + 1];
  12. for (int i = 1; i <= n; ++i) {
  13. points[i] = new Point(i);
  14. }
  15. for (int i = 0, u, v, val; i < m; ++i) {
  16. strs = reader.readLine().trim().split(" ");
  17. u = Integer.parseInt(strs[0]);
  18. v = Integer.parseInt(strs[1]);
  19. val = Integer.parseInt(strs[2]);
  20. points[u].nextList.add(new int[]{v, val});
  21. points[v].nextList.add(new int[]{u, val});
  22. }
  23. Comparator<int[]> comparator = new Comparator<int[]>() {
  24. @Override
  25. public int compare(int[] o1, int[] o2) {
  26. return Integer.compare(o1[1], o2[1]);
  27. }
  28. };
  29. Queue<int[]> queue = new PriorityQueue<>(comparator);
  30. points[1].isVisited = true;
  31. queue.addAll(points[1].nextList);
  32. int[] ans = new int[n - 1];
  33. int index = 0;
  34. while ((!queue.isEmpty()) && (index < n - 1)) {
  35. int[] min = queue.poll();
  36. if (points[min[0]].isVisited) {
  37. continue;
  38. }
  39. points[min[0]].isVisited = true;
  40. ans[index++] = min[1];
  41. for (int[] pair:points[min[0]].nextList){
  42. if (!points[pair[0]].isVisited){
  43. queue.add(pair);
  44. }
  45. }
  46. }
  47. if (index < n - 1) {
  48. System.out.println(-1);
  49. } else {
  50. int sum = 0;
  51. for (int i : ans) {
  52. // System.out.println(i);
  53. sum += i;
  54. }
  55. System.out.println(sum);
  56. }
  57. }
  58. }
  59. class Point {
  60. int id;
  61. boolean isVisited;
  62. List<int[]> nextList;
  63. public Point(int id) {
  64. this.id = id;
  65. isVisited = false;
  66. nextList = new ArrayList<>(id);
  67. }
  68. }