用C语言写一个求带权无向联通平面图的最小生成树的算法,用Kruskal算法
时间: 2024-02-21 15:57:42 浏览: 64
最小生成树Kruskal算法.zip,无向网的邻接矩阵生成最小生成树
5星 · 资源好评率100%
好的,下面是用C语言实现Kruskal算法求解带权无向联通平面图的最小生成树的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#define MAX_VERTEX_NUM 100 /* 最大顶点数 */
/* 定义边的结构体 */
typedef struct {
int u; /* 边的起点 */
int v; /* 边的终点 */
int w; /* 边的权重 */
} Edge;
/* 定义边集数组 */
typedef struct {
Edge edges[MAX_VERTEX_NUM * (MAX_VERTEX_NUM - 1) / 2]; /* 边集数组 */
int n; /* 边数 */
} EdgeArray;
/* 定义并查集 */
typedef struct {
int parent[MAX_VERTEX_NUM]; /* 父结点数组 */
int rank[MAX_VERTEX_NUM]; /* 秩数组 */
} DisjointSet;
/* 初始化并查集 */
void initDisjointSet(int n, DisjointSet *set) {
int i;
for (i = 0; i < n; i++) {
set->parent[i] = i;
set->rank[i] = 0;
}
}
/* 查找结点x所在集合的代表元 */
int find(int x, DisjointSet *set) {
if (set->parent[x] != x) {
set->parent[x] = find(set->parent[x], set);
}
return set->parent[x];
}
/* 合并结点x和结点y所在的集合 */
void unionSet(int x, int y, DisjointSet *set) {
int px = find(x, set);
int py = find(y, set);
if (px != py) {
if (set->rank[px] < set->rank[py]) {
set->parent[px] = py;
} else if (set->rank[px] > set->rank[py]) {
set->parent[py] = px;
} else {
set->parent[px] = py;
set->rank[py]++;
}
}
}
/* 比较两个边的权重 */
int compare(const void *a, const void *b) {
Edge *ea = (Edge *) a;
Edge *eb = (Edge *) b;
return ea->w - eb->w;
}
/* 使用Kruskal算法求解最小生成树 */
void kruskal(int n, EdgeArray *edges, EdgeArray *mst) {
DisjointSet set;
int i, j;
initDisjointSet(n, &set);
qsort(edges->edges, edges->n, sizeof(Edge), compare); /* 对边按权重排序 */
for (i = 0, j = 0; j < n - 1; i++) {
Edge e = edges->edges[i];
if (find(e.u, &set) != find(e.v, &set)) { /* 判断边的两个端点是否在同一集合中 */
mst->edges[j] = e; /* 将边加入最小生成树 */
j++;
unionSet(e.u, e.v, &set); /* 合并边的两个端点所在的集合 */
}
}
mst->n = j; /* 最小生成树的边数 */
}
int main() {
int n, m, i, j;
EdgeArray edges, mst;
scanf("%d%d", &n, &m);
edges.n = m;
for (i = 0; i < m; i++) {
scanf("%d%d%d", &edges.edges[i].u, &edges.edges[i].v, &edges.edges[i].w);
}
kruskal(n, &edges, &mst);
for (i = 0; i < mst.n; i++) {
printf("%d %d %d\n", mst.edges[i].u, mst.edges[i].v, mst.edges[i].w);
}
return 0;
}
```
以上代码中,使用了并查集来判断边的两个端点是否在同一集合中,从而避免形成环。使用快速排序来对边按权重排序。
阅读全文