Bessie 计划调查 NN(2 \le N \le 20002≤N≤2000)个农场的干草情况,它从 11 号农场出发。农场之间总共有 MM(1 \leq M \leq 10^41≤M≤10 4 )条双向道路,所有道路的总长度不超过 10^910 9 。有些农场之间存在着多条道路,所有的农场之间都是连通的。 Bessie 希望计算出该图中最小生成树中的最长边的长度。(C语言)
时间: 2024-02-13 12:01:15 浏览: 25
这是一道最小生成树的经典问题,可以使用 Kruskal 或 Prim 算法来解决。
下面是 Kruskal 算法的实现:
1. 将所有边按照权值从小到大排序。
2. 依次遍历每条边,若当前边的两个端点不在同一个连通块中,则将它们合并,并将该边加入最小生成树中。
3. 直到最小生成树中有 N-1 条边为止。
最后,最小生成树中的最长边即为所求。
代码如下:
```c
#include <stdio.h>
#include <stdlib.h>
#define MAXN 2002
#define MAXM 10002
typedef struct {
int u, v, w;
} Edge;
Edge edges[MAXM];
int fa[MAXN];
int cmp(const void *a, const void *b) {
return ((Edge *)a)->w - ((Edge *)b)->w;
}
int find(int x) {
if (fa[x] == x) return x;
return fa[x] = find(fa[x]);
}
void merge(int x, int y) {
x = find(x);
y = find(y);
if (x != y) fa[x] = y;
}
int main() {
int n, m;
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 = 0; i <= n; ++i) fa[i] = i;
int cnt = 0, ans;
for (int i = 0; i < m && cnt < n - 1; ++i) {
if (find(edges[i].u) != find(edges[i].v)) {
merge(edges[i].u, edges[i].v);
ans = edges[i].w;
++cnt;
}
}
printf("%d\n", ans);
return 0;
}
```
其中,cmp 函数是用来排序的比较函数,find 函数和 merge 函数是并查集的常规操作。