AcWing 859. Kruskal算法求最小生成树---java个人注解版
原题链接
简单
作者:
Acvv_scl
,
2021-03-10 01:37:23
,
所有人可见
,
阅读 315
步骤
- 将所有的边排序;
- 遍历所有的边,
- 看下 每条边的两个点是不是在同一个集合内(使用并查集)
- 如果不在同一个并查集 里面就合并 合并的同时需要更新两个 变量 res:最小生成树的长度;cnt 表示 合并点的次数
注意点
- 使用数组 来存储边与点的关系 es[N][3] e[i][0] 第i条起始点 e[i][1]第条边的终点;e[i][2]第i条边的边长
- 注意需要排序 数组 按照边长来排序
- 使用并查集 来合并点,生成最小生成树
- 合并点的同时 维护 res、cnt变量
import java.util.*;
public class Main{
static int INF=0x3f3f3f3f;
static int N=200010;
static int n;
static int m;
static int [][]es=new int[N][3];
//并查集
static int []p=new int[N];
static int find(int x){
if(p[x]!=x)p[x]=find(p[x]);
return p[x];
}
public static void main(String[]args){
Scanner sc=new Scanner (System.in);
Arrays.stream(es).forEach(t->Arrays.fill(t,INF));
n=sc.nextInt();
m=sc.nextInt();
for(int i=0;i<m;i++){
es[i][0]=sc.nextInt();
es[i][1]=sc.nextInt();
es[i][2]=sc.nextInt();
// System.out.println(es[i][0]+","+es[i][1]+","+es[i][2]);
}
Arrays.sort(es,(t1,t2)->t1[2]-t2[2]);
// Arrays.stream(es).forEach(t->System.out.println(Arrays.toString(t)));
for(int i=1;i<=n;i++){
p[i]=i;
}
//最小生成树的长度
int res=0;
//总共边加入到并查集的次数;
int cnt=0;
for(int i=0;i<m;i++){
int a=es[i][0];
int b=es[i][1];
int w=es[i][2];
//找各自的父节点;
a=find(a);b=find(b);
//父节点 不相等说明 不在一个集合里面,将两个点 合并;并更新树的长度 以及添加到并查集的次数
if(a!=b){
res+=w;
cnt++;
p[a]=b;
}
}
//加入到并查集的次数 小于n-1 那就说明 有不连通的点;
if(cnt<n-1){
System.out.println("impossible");
}else{
System.out.println(res);
}
}
}