-
问题描述:
用克鲁斯卡尔(Kruskal)算法求无向网的最小生成树。
-
输入:
输入数据第一行为两个正整数n(1<n<=30)和m(1<m<100),分别表示顶点数和边数。后面紧跟m行数据,每行数据是一条边的信息,包括三个数字,分别表示该边的两个顶点和边上的权值。
-
输出:
按顺序输出Kruskal算法求得的最小生成树的边集,每行一条边,包括三个数字,分别是该边的两个顶点和边上的权值,其中第一个顶点的编号应小于第二个顶点的编号。
-
示例输入
8 11
1 2 3
1 4 5
1 6 18
2 4 7
2 5 6
3 5 10
3 8 20
4 6 15
4 7 11
5 7 8
5 8 12 -
示例输出
1 2 3
1 4 5
2 5 6
5 7 8
3 5 10
5 8 12
4 6 15 -
完整代码
#include<stdio.h>
struct E
{
int u;
int v;
int w;
}Edge[101];
int main()
{
int n,m,i,vest[50],j,count,sv,su;
E t;
scanf("%d %d",&n,&m);
for(i=1;i<=n;i++)
vest[i]=i;
for(i=1;i<=m;i++)
scanf("%d %d %d",&Edge[i].u,&Edge[i].v,&Edge[i].w);
for(i=1;i<=m;i++)//将边按权值大小顺序排列
for(j=1;j<m;j++)
if(Edge[j].w>Edge[j+1].w)
{
t=Edge[j];
Edge[j]=Edge[j+1];
Edge[j+1]=t;
}
count=1;j=1;
while(count<n)
{
if(vest[Edge[j].u]!=vest[Edge[j].v])
{
count++;
if(Edge[j].u>Edge[j].v)
printf("%d %d %d\n",Edge[j].v,Edge[j].u,Edge[j].w);
else
printf("%d %d %d\n",Edge[j].u,Edge[j].v,Edge[j].w);
su=vest[Edge[j].u];sv=vest[Edge[j].v];
for(i=1;i<=n;i++)
{
if(vest[i]==sv)
vest[i]=su;//两个集合统一编号
}
}
j++;//扫描下一个边
}
return 0;
}
~~
~~ 第一次写的时候发生了如上错误,很久没有找出来。原因是:当i=Edge[j].v时,赋值之后上面if里的vest[Edge[j].v]会发生改变,以至于使下面vest值等于被改变之前的vest[Edge[j].v]赋不上值。