859. Kruskal algorithm for minimum spanning tree
①. Title
②. Thinking
③. Learning points
克鲁斯卡尔算法_稀疏图_并查集
④. Code implementation
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
public class Main {
static class Edge{
int x;
int y;
int w;
public Edge(int x,int y,int w){
this.x = x;
this.y = y;
this.w = w;
}
}
static int INF=0x3f3f3f3f;
static int n,m,cnt;
static Edge[] edges;
static int[] p;//存储节点的父节点 并查集
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] s = br.readLine().split(" ");
n = Integer.parseInt(s[0]);
m = Integer.parseInt(s[1]);
edges=new Edge[m];
p=new int[n+1];
//初始化并查集模板
for (int i = 1; i < n; i++) {
p[i]=i;
}
for (int i = 0; i <m; i++) {
String[] s2 = br.readLine().split(" ");
int x = Integer.parseInt(s2[0]);
int y = Integer.parseInt(s2[1]);
int w = Integer.parseInt(s2[2]);
Edge e = new Edge(x,y,w);
edges[i]=e;
}
//将所有边按权重从小到大排序
Arrays.sort(edges,(a,b)->a.w-b.w);
int res=0;
//枚举每条边a b 权重w
for (int i = 0; i <m; i++) {
Edge e=edges[i];
//使用并查集模板, 比较两个集合的祖宗节点是否相同
int fx=find(e.x);
int fy=find(e.y);
//若两个集合不连通,将它们合并
if(fx!=fy) {
p[fx]=fy;
res+=e.w;
cnt++;
}
}
//cnt<n-1表示不能遍历所有点 直接impossible
if(cnt<n-1) {
System.out.println("impossible");
}else {
System.out.println(res);
}
}
//并查集根据父节点递归向上查找祖宗节点
static int find(int x) {
if(p[x]!=x) {
p[x]=find(p[x]);
}
return p[x];
}
}