克鲁斯卡尔法求最小生成树


#include "stdlib.h"
#include "stdio.h"
#define MAX 100
#define M (MAX*(MAX-1)/2)
/*
Test data:
6 0 1 1 0 2 33 0 3 43 0 4 5 0 5 32 1 2 3 1 3 4 1 4 5 1 5 76 2 3 2 2 4 5 2 5 6 3 4 5 3 5 665 4 5 4 -1 -1 -1
result:
(V0 ,V1 )(V2 ,V3 )(V1 ,V2 )(V4 ,V5 )(V0 ,V4 )
The sum is:15
*/
/*每次从边中选取最小边,直到领点都选取完,并输出T的各条边及各条边的权之和*/
/*无向图带权结构体*/
typedef struct
{
int i,j,w;
}Edge;
/*按 权 排序*/
void bsort(Edge a[],int n)
{
Edge t;
int i,j,ok;
for(i=1;i<n;i++)
{
ok=1;
for(j=0;j<n-i;j++)
if(a[j].w>a[j+1].w)
{
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
ok=0;
}
if(ok)break;
}
}
/*读入权信息*/
void read(Edge a[],int *c,int n)
{
int i,j,w;
*c=0;
do
{
scanf("%d%d%d",&i,&j,&w);
if(i==-1||j==-1||w==-1)break;
if(i<0||i>=n||j<0||j>=n||w<=0||i==j) continue;
if(*c>=M)
{
exit(-2);
}
a[*c].i=i;a[*c].j=j;a[*c].w=w;(*c)++;
}while(9);
}
/*sameTree链表功能 表示两个顶点是否在一棵树下,初始化为-1,*/
int sameTree[MAX];
int inSameTree(int i,int j)
{
int s;
if(sameTree[i]==-1)
{
if(sameTree[j]==-1)
{
sameTree[i]=j;
sameTree[j]=i;
}
else
{
sameTree[i]=sameTree[j];
sameTree[j]=i;
}
return 0;
}
else
{
if(sameTree[j]==-1)
{
sameTree[j]=sameTree[i];
sameTree[i]=j;
return 0;
}
else
{
s=i;
//循环判定该两点的边
while(sameTree[s]!=i)
{
if(sameTree[s]==j)return 1;
s=sameTree[s];
}
//如果i j存在 没有连通
sameTree[s]=sameTree[j];
sameTree[j]=i;
return 0;
}
}
}
void MST(Edge a[],int n,int vnum)
{
int c=0,i,sum=0;
//从n条边中选取vnum-1条边
for(i=0;i<n;i++)
{
if(inSameTree(a[i].i,a[i].j))continue;
sum+=a[i].w;
printf("(V%-2d,V%-2d)",a[i].i,a[i].j);
if(++c%8==0)printf("\n");
if(c>=vnum-1)
{
printf("\nThe sum is:%d\n",sum);
return;
}
}
if(c<vnum-1)printf("\nThe graph is not connect\n");
}

void main()
{
Edge a[M];
int i,n,vnum;//n边数 vnum顶点个数
printf("enter verxnum and edges with weight:\n");
scanf("%d",&vnum);
if(vnum<1||vnum>MAX)
{
printf("error:vnum mun must be in [1..%d]\n",MAX);
return;
}
read(a,&n,vnum);
bsort(a,n);
for(i=0;i<vnum;i++)
{
sameTree[i]=-1;
}
MST(a,n,vnum);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值