import java.util.*; import java.io.*; public class Main { static class Edge { int u, v, w, id; Edge(int u, int v, int w, int id) { this.u = u; this.v = v; this.w = w; this.id = id; } } static class UnionFind { private int[] parent; private int[] rank; public UnionFind(int size) { parent = new int[size + 1]; rank = new int[size + 1]; for (int i = 1; i <= size; i++) { parent[i] = i; rank[i] = 1; } } public int find(int x) { if (parent[x] != x) { parent[x] = find(parent[x]); } return parent[x]; } public void union(int x, int y) { int xRoot = find(x); int yRoot = find(y); if (xRoot == yRoot) return; if (rank[xRoot] < rank[yRoot]) { parent[xRoot] = yRoot; } else if (rank[xRoot] > rank[yRoot]) { parent[yRoot] = xRoot; } else { parent[yRoot] = xRoot; rank[xRoot]++; } } } public static void main(String[] args) { Scanner in = new Scanner(System.in); int n = in.nextInt(); int m = in.nextInt(); Edge[] edges = new Edge[m]; for (int i = 0; i < m; i++) { int u = in.nextInt(); int v = in.nextInt(); int w = in.nextInt(); edges[i] = new Edge(u, v, w, i + 1); } Arrays.sort(edges, Comparator.comparingInt((Edge e) -> e.w).thenComparingInt( e -> e.id)); UnionFind uf = new UnionFind(n); List<Integer> selected = new ArrayList<>(); long sum = 0; for (Edge e : edges) { if (selected.size() == n - 1) break; int uRoot = uf.find(e.u); int vRoot = uf.find(e.v); if (uRoot != vRoot) { uf.union(uRoot, vRoot); sum += e.w; selected.add(e.id); } } System.out.println(sum); StringBuilder sb = new StringBuilder(); for (int id : selected) { sb.append(id).append(' '); } System.out.println(sb.toString().trim()); } }
https://www.nowcoder.com/discuss/727521113110073344
思路:
- Edge类:用于存储边的信息,包括两个顶点、权值和输入时的编号。
- UnionFind类:并查集数据结构,用于高效管理顶点的连通性,支持路径压缩和按秩合并。
- 主函数:读取输入数据,对边按权值和编号排序,使用并查集逐步构建MST,记录总权值和选中的边,最后输出结果。