用c语言实现最小生成树。具体要求如下:给定各个点之间边的权,最后输出所有所选的权以及该权两端的结点
时间: 2024-02-05 19:12:07 浏览: 73
最小生成树
实现最小生成树的经典算法是Prim算法和Kruskal算法,这里我们给出Kruskal算法的C语言实现。
Kruskal算法的基本思路是:首先将所有边按照权值从小到大排序,然后依次选择权值最小的边,判断这条边的两个端点是否在同一个连通块中,如果不在同一个连通块中,则将这条边加入最小生成树中,并将两个连通块合并起来。
下面是C语言实现Kruskal算法的代码,假设图的顶点数为N,边的数量为M,边按照权值从小到大存储在一个结构体数组edges中,每条边有两个端点和权值,最终得到的最小生成树存储在一个结构体数组tree中,其中包含每条边的两个端点和权值。
```c
#include <stdio.h>
#include <stdlib.h>
#define MAXN 1000
#define MAXM 10000
typedef struct {
int u, v; // 边的两个端点
int w; // 边的权值
} Edge;
int cmp(const void *a, const void *b)
{
Edge *e1 = (Edge *)a;
Edge *e2 = (Edge *)b;
return e1->w - e2->w;
}
int p[MAXN]; // 并查集数组
int find(int x)
{
if (p[x] != x) {
p[x] = find(p[x]);
}
return p[x];
}
void merge(int x, int y)
{
p[find(x)] = find(y);
}
int main()
{
int N, M;
Edge edges[MAXM];
Edge tree[MAXN];
scanf("%d%d", &N, &M);
for (int i = 0; i < M; i++) {
scanf("%d%d%d", &edges[i].u, &edges[i].v, &edges[i].w);
}
qsort(edges, M, sizeof(Edge), cmp);
for (int i = 1; i <= N; i++) {
p[i] = i;
}
int k = 0;
for (int i = 0; i < M && k < N - 1; i++) {
int u = edges[i].u, v = edges[i].v, w = edges[i].w;
if (find(u) != find(v)) {
merge(u, v);
tree[k++] = edges[i];
}
}
for (int i = 0; i < k; i++) {
printf("%d %d %d\n", tree[i].u, tree[i].v, tree[i].w);
}
return 0;
}
```
这段代码首先读入图的顶点数N和边数M,然后读入每条边的起点、终点和权值,并将边按照权值从小到大排序。接下来初始化并查集数组p,然后依次处理每条边,如果这条边的两个端点不在同一个连通块中,就将它加入最小生成树中,并将这两个连通块合并起来。最后输出最小生成树的每条边的两个端点和权值。
阅读全文