1. 程式人生 > >(Java資料結構和演算法)最小生成樹---Kruskal演算法(並查集)

(Java資料結構和演算法)最小生成樹---Kruskal演算法(並查集)

該文章利用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; } }

在這裡插入圖片描述