克鲁斯卡尔(Kruskal)算法
(只与边相关)
算法描述:克鲁斯卡尔算法需要对图的边进行访问,所以克鲁斯卡尔算法的时间复杂度只和边又关系,可以证明其时间复杂度为O(nlogn)。
算法过程:
1.将图各边按照权值进行排序
2.将图遍历一次,找出权值最小的边,(条件:此次找出的边不能和已加入最小生成树集合的边构成环),若符合条件,则加入最小生成树的集合中。不符合条件则继续遍历图,寻找下一个最小权值的边。
3.递归重复步骤1,直到找出n-1条边为止(设图有n个结点,则最小生成树的边数应为n-1条),算法结束。得到的就是此图的最小生成树。
克鲁斯卡尔(Kruskal)算法因为只与边相关,则适合求稀疏图的最小生成树。而prime算法因为只与顶点有关,所以适合求稠密图的最小生成树。
#include"stdio.h"
#include"stdlib.h"
int set[5000];
struct node
{
int a,b,dis;
}aa[5002];
int find(int x)
{
int r,i;
r=x;
while(r!=set[r])
r=set[r];
while(set[x]!=r)
{
i=set[x];
set[x]=r;
x=i;
}
return r;
}
int cmp(const void*a,const void*b)
{
struct node *c,*d;
c=(struct node*)a;
d=(struct node*)b;
return c->dis-d->dis;
}
int main()
{
int n,m,i,j,ans;
int x,y;
while(scanf("%d",&n)!=EOF&&n)
{
m=n*(n-1)/2;
for(i=0;i<=5000;i++)
set[i]=i;
for(i=0;i<m;i++)
scanf("%d%d%d",&aa[i].a,&aa[i].b,&aa[i].dis);
qsort(aa,m,sizeof(aa[0]),cmp);
ans=0;
for(i=0;i<m;i++)
{
x=find(aa[i].a);
y=find(aa[i].b);
if(x!=y)
{
ans+=aa[i].dis;
if(x<y) set[y]=x;
else set[x]=y;
}
}
printf("%d\n",ans);
}
return 0;
}