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,记录总权值和选中的边,最后输出结果。



京公网安备 11010502036488号