
题目说了一大堆废话,总结下来就是找到一个图的最小生成树,输出该树的最长边。
在这里我用Kruskal算法实现。
#include <iostream>
#include <algorithm>
using namespace std;
int n, m, root;
typedef struct edge {
int x, y;
int z;
} Edge;
bool compare(Edge e1, Edge e2) {
return e1.z < e2.z;
}
Edge edges[100001];
int parent[50001];
int find_root(int x) {
if (parent[x] == x) return x;
else {
parent[x] = find_root(parent[x]);
return parent[x];
}
}
void merge(int u, int v) {
int r1 = find_root(u), r2 = find_root(v);
parent[r2] = r1;
}
int main()
{
cin >> n >> m >> root;
for (int i = 0; i < m; i++) {
int a0, a1, a2;
cin >> a0 >> a1 >> a2;
Edge e;
e.x = a0;
e.y = a1;
e.z = a2;
edges[i] = e;
}
sort(edges, edges + m,compare);
for (int i = 0; i < n; i++) {
parent[i] = i;
}
int n0 = 0, n1 = 0;
while (n0 < n - 1)
{
if (find_root(edges[n1].x) != find_root(edges[n1].y)) {
merge(edges[n1].x, edges[n1].y);
n0++;
}
n1++;
}
cout << edges[n1-1].z << endl;
}
有几个需要注意的点。
第一,在merge函数中,一定要找到两个点在各自树中的根节点,将一个根节点设置为另一个根节点的父节点。
第二,程序很有可能出现运行超时的情况,例如我们将find_root函数修改如下,就会超时:
int find_root(int x) {
if (parent[x] == x) return x;
else {
return find_root(parent[x]);
}
}
这是因为树的高度太高了,寻找根节点的速度就慢。我们需要在每次寻找根节点的时候顺便更新一下parent。
本文介绍了如何运用Kruskal算法解决图的最小生成树问题,并着重强调在实现过程中如何避免超时,通过优化find_root函数来减少查找根节点的时间复杂度,最终找到最小生成树中的最长边。程序中展示了Kruskal算法的详细步骤,包括边的排序、树的合并等关键操作。
3270

被折叠的 条评论
为什么被折叠?



