Bessie 计划调查 N(2≤N≤2000)个农场的干草情况,它从 1 号农场出发。农场之间总共有 M(1≤M≤10^4 )条双向道路,所有道路的总长度不超过 10^9 。有些农场之间存在着多条道路,所有的农场之间都是连通的。 Bessie 希望计算出该图中最小生成树中的最长边的长度。要求第 1 行输入两个整数 N和 M; 接下来 M 行,每行输入三个整数,表示一条道路的起点终点和长度。要求输出一个整数,表示最小生成树中的最长边的长度。用C语言编程
时间: 2024-01-22 16:18:18 浏览: 140
以下是使用 Kruskal 算法求解该问题的 C 语言代码:
```c
#include <stdio.h>
#include <stdlib.h>
#define MAX_N 2000
#define MAX_M 10000
#define MAX_LEN 1000000000
struct Edge {
int u, v, w;
};
int n, m;
struct Edge edges[MAX_M];
int parent[MAX_N + 1];
int cmp(const void* a, const void* b) {
return ((struct Edge*)a)->w - ((struct Edge*)b)->w;
}
int find(int x) {
if (parent[x] == x) {
return x;
}
return parent[x] = find(parent[x]);
}
void union_set(int x, int y) {
int px = find(x), py = find(y);
if (px != py) {
parent[px] = py;
}
}
int kruskal() {
int i, ans = 0;
for (i = 1; i <= n; ++i) {
parent[i] = i;
}
qsort(edges, m, sizeof(struct Edge), cmp);
for (i = 0; i < m; ++i) {
if (find(edges[i].u) != find(edges[i].v)) {
union_set(edges[i].u, edges[i].v);
ans = edges[i].w;
}
}
return ans;
}
int main() {
int i;
scanf("%d%d", &n, &m);
for (i = 0; i < m; ++i) {
scanf("%d%d%d", &edges[i].u, &edges[i].v, &edges[i].w);
}
int max_edge = kruskal();
printf("%d\n", max_edge);
return 0;
}
```
在主函数中,我们首先读入农场数量和道路数量,然后读入每条道路的起点、终点和长度,并将它们存储在 edges 数组中。随后,我们调用 kruskal 函数计算最小生成树中的最长边的长度,并将其输出。
在 kruskal 函数中,我们首先初始化并查集,然后按照边权从小到大排序所有边。接着,我们依次遍历每条边,如果它的两个端点不在同一个连通块中,则将它们合并,并更新最长边的长度。最后,我们返回最长边的长度即可。
由于并查集的时间复杂度为 O(alpha(n)),而 Kruskal 算法的时间复杂度为 O(m log m),其中 alpha(n) 是阿克曼函数的反函数,因此该算法的时间复杂度为 O(m log m),可以通过本题的所有测试数据。
阅读全文