标题
最小生成树
时间限制
2 S
内存限制
10000 Kb
问题描述:
见习题集P152。用克鲁斯卡尔(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
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
typedef struct Edge
{
int v1, v2;
int wight;
}Edge;
int main()
{
int n, m;//结点数和边数
int i, j, k = 0;
int count = 0;
Edge edge[100];//边集
int vest[30];//判断是否成环的编号数组
scanf("%d %d", &n, &m);
for (i = 0; i < m; i++)
{
scanf("%d %d %d", &edge[i].v1, &edge[i].v2, &edge[i].wight);
if(edge[i].v1 > edge[i].v2)
{
int t = edge[i].v1;
edge[i].v1 = edge[i].v2;
edge[i].v2 = t;
}
}
for (i = 1; i <= n; i++)//初始化编号数组
vest[i] = i;
for (i = 0; i < m - 1; i++)//排序
{
for (j = 0; j < m - i - 1; j++)
{
if (edge[j].wight > edge[j + 1].wight)
{
Edge t = edge[j];
edge[j] = edge[j + 1];
edge[j + 1] = t;
}
}
}
for (i = 0; i < m && count < n - 1; i++)
{
if (vest[edge[i].v1] != vest[edge[i].v2])//说明不构成环,打印
{
printf("%d %d %d\n", edge[i].v1, edge[i].v2, edge[i].wight);
count++;
int flag1 = vest[edge[i].v1];
int flag2 = vest[edge[i].v2];
for (j = 1; j <= n; j++)
{
if (vest[j] == flag2)//把全部编号为flag2的结点改为flag1
vest[j] = flag1;
}
}
}
return 0;
}