最小生成树之Kruskal算法(图论) By ACReaper

这是利用并查集实现的比较高效的Kruskal算法,用于算出最小生成树的权!

注意该算法并没有维护最小生成树的形态,而只是算出其权值而已,所以离实际应用还有距离!


#include <stdio.h>
#include <stdlib.h>
#define MAXN 1000
int v[MAXN];
int u[MAXN];
int w[MAXN];
int p[MAXN];
int r[MAXN];
int n,m;
int find(int x);
int cmp(const void *a,const void *b);
int Kruskal();
int main(){
	while(scanf("%d%d",&n,&m) != EOF){
		for(int i = 1; i <= m; i++){//输入m条边 
			scanf("%d%d%d",u + i, v + i, w + i);
		}
		printf("%d\n",Kruskal());
	}
	return 0;
}
int find(int x){
	return x == p[x]? x : find(p[x]);
}
int cmp(const void *a,const void *b){
	int *p = (int *)a;
	int *q = (int *)b;
	if(w[*p] < w[*q])
		return -1;
	else
		if(w[*p] == w[*q])
			return 0;
		else
			return 1;
} 

int Kruskal(){
	for(int i = 1; i <= n; i++){
		p[i] = i;
	}
	
	for(int i = 1; i <= m; i++){
		r[i] = i;
	}
	qsort(r + 1,m,sizeof(int),cmp);
	int ans = 0;
	for(int i = 1; i <= m; i++){
		int e = r[i];//从最小的边开始选择 
		int x = find(u[e]);
		int y = find(v[e]);
		if( x != y){//不属于同一集合 
			ans += w[e]; 
			p[y] = x;
		} 
	}
	return ans;
} 

2013 04 23

By ACReaper

posted @ 2013-04-23 23:21  算法黑魔王  阅读(135)  评论(0编辑  收藏  举报