(Java資料結構和演算法)最小生成樹---Kruskal演算法(並查集)
阿新 • • 發佈:2018-12-01
該文章利用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;
}
}