用 c 语言, 采用破圈法求一个带权连通图的最小生成树,并测试。
时间: 2024-03-10 22:49:00 浏览: 105
用“破圈法”求全部最小生成树的算法 (2006年)
以下是使用C语言实现破圈法求解最小生成树的示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#define MAXN 100010
#define MAXM 200010
int n, m;
int p[MAXN];
struct Edge
{
int a, b, w;
}edges[MAXM];
int cmp(const void* a, const void* b)
{
return ((Edge*)a)->w - ((Edge*)b)->w;
}
int find(int x)
{
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
int main()
{
scanf("%d%d", &n, &m);
for (int i = 0; i < m; i ++)
scanf("%d%d%d", &edges[i].a, &edges[i].b, &edges[i].w);
qsort(edges, m, sizeof(Edge), cmp);
for (int i = 1; i <= n; i ++)
p[i] = i;
int res = 0, cnt = 0;
for (int i = 0; i < m; i ++)
{
int a = edges[i].a, b = edges[i].b, w = edges[i].w;
a = find(a), b = find(b);
if (a != b)
{
p[a] = b;
res += w;
cnt ++;
}
}
if (cnt < n - 1) printf("impossible\n");
else printf("%d\n", res);
return 0;
}
```
在上述代码中,我们同样使用结构体`Edge`来表示图中的边,其包含起点、终点和权值。首先,我们读入图的节点数和边数,然后读入每条边的信息,并按照权值从小到大排序。接着,我们初始化每个节点的祖先为它本身,遍历每条边,如果该边连接的两个节点不在同一个连通块中,就将这条边加入最小生成树中,并将这两个节点合并成一个连通块。最后,如果最小生成树的边数小于n-1,则说明无法构成一颗生成树,输出"impossible";否则输出最小生成树的总权值。
阅读全文