newwy
奋斗在IT路上的小蜗牛。一步一步往上爬,爬到小牛,在到大牛,然后是神牛,然后是犇,然后就可以离开IT行业,回归大自然了。 远离IT,珍爱生命!!! 记录学习的点滴。
#include <iostream>
#define INF 0x3fff
#define MAXN 100
using namespace std;
typedef struct 
{
	int s;//start结点 
	int e;//end结点 
	int w;//weight权值 
}edge;
edge e[MAXN*MAXN/2];//存储每一条边的数组 
void insertsort(edge e[],int n)//直接插入排序 
{
	int i,j;
	edge temp;
	for(i = 0 ; i < n ;i++)
	{
		temp = e[i];
		j = i - 1;
		while(j >= 0 && temp.w < e[j].w)
		{
			e[j+1]= e[j];
			j--;
		}
		e[j+1] = temp;
	}
}
void kruskal(int n,int mat[][MAXN])//Kruskal实现 
{
	int i,j,k,m1,m2,sn1,sn2;
	edge e[MAXN*MAXN/2];
	int vset[MAXN];
	for(i = 0 ; i < n ; i++)//每个节点都初始化 
		vset[i] = i;
	k = 0;

	for(i = 0 ; i < n;i++)
	{
		for(j = 0 ; j < n;j++)
		{
			if(mat[i][j] != 0 && mat[i][j] != INF)//将邻接矩阵中的每一条边都加入到边权值的数组中 
			{
				e[k].s = i;e[k].e = j;
				e[k].w = mat[i][j];
				k++;
			}
		}
	}
	insertsort(e,k);//对边的权值从大到小排序,这里采用直接插入排序,如果采用堆排序时间复杂度会减少 
	int cnt = 1 ;//记录加入到最小生成树的边的数量 
	k = 0;
	while(cnt < n)
	{
		m1 = e[k].s; m2 = e[k].e;//记录这条边的start , end 结点 
		sn1 = vset[m1]; sn2 = vset[m2];//看这两个结点属于哪一个set 
		if(sn1 != sn2)//如果不等,说明这两个结点不在一个生成树中,合并 
		{
			printf("edge (%d,%d):%d is added!\n", e[k].s,e[k].e,e[k].w);
			cnt++;
			for(i = 0 ; i < n ; i++)
			{
				if(vset[i] == sn2)//把所有的原有的生成树的结点重新加入到新的生成树中 
					vset[i] = sn1;
			}
		}
		k++;//k为边的权值数组的Index 
	}	

}
int mat[MAXN][MAXN];
int main()
{
	memset(mat,0,sizeof(mat));
	int num;
	printf("please input vertex:");
	scanf("%d",&num);
	int n;
	printf("input the number of edge:");
	scanf("%d",&n);
	int t = n;
	while(t--)
	{
		int a,b,cost;
		scanf("%d %d %d",&a,&b,&cost);
		--a,--b;
		if(mat[a][b] == 0 && mat[b][a] == 0 || cost < mat[a][b] )
			mat[a][b] = mat[b][a] = cost;
	}
	int i,j;
	for(i = 0 ; i < num;i++){
		for(j = 0 ; j < num; j++)
			printf("%4d",mat[i][j]);printf("\n");}
	kruskal(num,mat);
/*
test data:
6
10
1 2 6
1 3 1
1 4 5
2 3 5
3 4 5
2 5 3
3 5 6
3 6 4
4 6 2
5 6 6
*/	
	return 0;
}

posted on 2010-11-20 13:55  newwy  阅读(453)  评论(0编辑  收藏  举报