样例输入
4
5
1
1 2 3
1 3 4
1 4 5
2 3 8
3 4 2
样例输出
4
样例说明
下图是样例说明。
题意:
对于一个图,求树结构传输时间,但我们需要注意
,就是每个子节点走向根节点的每一层的边的权值要最大的。该题目,乍一看,感觉挺难的,但仔细读题目,尤其是看样例图解,我们会发现,这就是一个最大值最小问题,求每次
的最大值的最小情况。
题目思路:
首先要把图转化为树,有很多种情况,求最大的权值的最小情况,那不就是一个最小生成树问题嘛,这时候树的权值最小,而最小生成树,最小生成树种,最大边就是最后加入的一条边,这里我准备使用 kruskal算法求出最小生成树,显然最后加入的那一条边,就是权值最大的边,也就是答案。
关于kruskal算法,大家可以看我的另一篇博客:https://blog.csdn.net/ding_programmer/article/details/89512540
和这一篇博客的kruskal算法一模一样,学会了 kruskal算法,我们就可以用来解题了,算法如下:
#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int fa[100100];
struct Edge {
int x, y, w;
};
int cmp(Edge &e1, Edge &e2) {
if (e1.w != e2.w) {
return e1.w < e2.w;
}
else {
return e1.x < e2.x;
}
}
int find(int x) {
return fa[x] == x ? fa[x] : fa[x] = find(fa[x]);
}
void uniton_tree(int x, int y) {
int fx = find(x);
int fy = find(y);
if (fx != fy) {
fa[fx] = fy;
}
}
int main()
{
int n, m, rt,x,y,w;
int cnt =0;
int sum = 0;
Edge e[100100];
scanf("%d%d%d", &n, &m, &rt);
for (int i = 1; i <= m; i++) {
scanf("%d%d%d",&x,&y,&w);
e[i].x = x;
e[i].y = y;
e[i].w = w;
}
sort(e + 1, e + m + 1, cmp);
for (int i = 1; i <= n; i++) {
fa[i] = i;
}
for (int i = 1; i <= m; i++) {
int f1 = find(e[i].x);
int f2 = find(e[i].y);
int z = e[i].w;
if (f1 != f2) {
cnt++;
uniton_tree(f1, f2);
}
if (cnt == n - 1) {
sum = z;
break;
}
}
cout << sum << endl;
return 0;
}
然后学会了之后,就可以很高兴的发现,自己解出来了: