最小生成树之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
浙公网安备 33010602011771号