克鲁斯卡尔(Kruskal)算法

克鲁斯卡尔(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;
}


posted on 2012-07-27 08:24  Slege  阅读(532)  评论(0编辑  收藏  举报

导航