【java,Kruskal】实现最小生成树。学习链接:学习链接
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Scanner;
class Edge{
//边 a b c的含义是,a、b节点之间的路径权重(长度)是c
int a;
int b;
int c;
Edge(int a,int b,int c) {
this.a = a;
this.b = b;
this.c = c;
}
}
public class MST {
private static int vertexNum; //顶点的数量
private static int edgeNum; //边的数量
private static Edge[] edgeArr; //用来存储边
private static int[] p; //利用并查集
private static int chooseEdgeNum = 0;//被选中的边的个数
private static ArrayList<Integer> chooseEdge = new ArrayList<Integer>(); //记录被选中的边的下标
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
vertexNum = sc.nextInt();
edgeNum = sc.nextInt();
edgeArr = new Edge[edgeNum]; //初始化存储边的数组
p = new int[vertexNum+1];
for (int i = 1; i <= vertexNum; i ++) {
p[i] = i;//初始化并查集
}
//输入边
int a,b,c;
for(int i = 0 ; i < edgeNum ; i++) {
sc.nextLine();
a = sc.nextInt();
b = sc.nextInt();
c = sc.nextInt();
edgeArr[i] = new Edge(a,b,c);
}
// for(int i = 0 ; i < edgeNum ; i++) {
// System.out.println(edgeArr[i].a+" "+edgeArr[i].b+" "+edgeArr[i].c);
// }
//Kruskal
boolean temp = Kruskal();
if(Kruskal() == true) {
System.out.println("可以构成最小生成树,最小生成树包含的边有:");
for(int i = 0; i<chooseEdge.size(); i++) {
int m = chooseEdge.get(i);
System.out.println("边: "+edgeArr[i].a+" --> "+edgeArr[i].b+" ,权重:"+edgeArr[i].c);
}
}
else {
System.out.println("不可以构成最小生成树");
}
}
public static boolean Kruskal() {
//对edge数组从小到大进行排序
for(int i = 1 ; i < edgeNum ; i++) {
Edge temp = edgeArr[i]; //定义待交换的元素
int j; //定义待插入的位置
for(j = i ; j > 0 && temp.c < edgeArr[j-1].c ; j--) {
edgeArr[j] = edgeArr[j-1];
}
edgeArr[j] = temp;
}
//逐个把边加入进去
for(int i = 0 ; i < edgeNum ; i++) {
Edge temp = edgeArr[i];
int a = temp.a;
int b = temp.b;
int c = temp.c;
//查看顶点a 顶点b是否属于同一个集合
int m = find(a);
int n = find(b);
if(m!=n) {
//如果a、b两者不属于同一个集合,将a、b这条边加入到总集合中去
p[m] = n;
//System.out.println("加入:"+a+" "+b+" 祖先分别是"+m+" "+n);
chooseEdgeNum++;
chooseEdge.add(i);
}
}
if (chooseEdgeNum < vertexNum - 1) {
// 边树小于n-1,不能构造最小生成树
return false;
}
else {
return true;
}
}
public static int find(int x) {
//寻找x点的祖宗节点
if (p[x] != x) {
p[x] = find(p[x]);
}
return p[x];
}
}