该文章利用prime算法求得连通图的最小生成树对应的边权最小和,prime算法是从顶点的角度思考和解决问题。本文介绍的Kruskal算法将从边的角度考虑并解决问题,利用了并查集方便地解决了最小生成树的问题。
//并查集
class UnionSameSet{
public int[] parent;
public int[] rank;
public int n;
public UnionSameSet(int n){
this.n = n;
parent = new int[n];
rank = new int[n];
}
public void init(){
for(int i = 0; i < n; i++){
parent[i] = i;
rank[i] = 1;
}
}
public int findRoot(int v){
if(v == parent[v]){
return v;
}else{
return findRoot(parent[v]);
}
}
public void unite(int x, int y){
x = findRoot(x);
y = findRoot(y);
if(x == y){
return;
}else if(rank[x] < rank[y]){
parent[x] = y;
if(rank[y] < rank[x] + 1){
rank[y] = rank[x] + 1;
}
}else{
parent[y] = x;
if(rank[x] < rank[y] + 1){
rank[x] = rank[y] + 1;
}
}
}
}
class EdgeNode{
public int st;
public int en;
public int weight;
}
class MyComparator implements java.util.Comparator{
public int compare(Object ee1, Object ee2){
EdgeNode e1 = (EdgeNode)ee1;
EdgeNode e2 = (EdgeNode)ee2;
if(e1.weight < e2.weight){
return -1;
}else if(e1.weight > e2.weight){
return 1;
}else{
return 0;
}
}
}
public class Main {
public static void main(String[] args){
java.util.Scanner scan = new java.util.Scanner(System.in);
System.out.print("请输入边数:");
int n = scan.nextInt();
EdgeNode[] edges = new EdgeNode[n];
for(int i = 0; i < n; i++){
System.out.println("请输入第"+(i+1)+"条边的两个顶点及权重:");
edges[i] = new EdgeNode();
edges[i].st = scan.nextInt();
edges[i].en = scan.nextInt();
edges[i].weight = scan.nextInt();
}
System.out.println("最小生成树边权之和:"+kruskal(n, edges));
}
public static int kruskal(int n, EdgeNode[] edges){
int sum = 0;
UnionSameSet uss = new UnionSameSet(n);
uss.init();
java.util.Arrays.sort(edges, new MyComparator());
for(int i = 0; i < n; i++){
if(uss.findRoot(edges[i].st) != uss.findRoot(edges[i].en)){
uss.unite(edges[i].st, edges[i].en);
sum += edges[i].weight;
}
}
return sum;
}
}