题目
样例输入
4
5
1
1 2 3
1 3 4
1 4 5
2 3 8
3 4 2
样例输出
4
样例说明
下图是样例说明。
思路
- 题目要求
题目要求的是生成一个树,使这棵树的最大值是所有生成树中最小的。这个最大值题目中是这么描述的:
- 每层中选出最大的边
- 所有层的最大的边中再选出最大的边
说的有点绕,但看懂后就很简单了,这个最大值就是这棵树的最大边。也就是要生成这样一棵树,这棵树的最大边是所有生成树中最小的,最小生成树就满足该条件。
- 最小生成树算法
- prime算法
- Kruskal算法
最小生成树就是最后要求的,生成树中最大边即最后输出。
下为Kruskal算法
#include <stdio.h>
#include <algorithm>
using namespace std;
struct edge{
int n1;
int n2;
int w;
bool operator <( edge e){
return w<e.w;
}
};
int node[500001];
// 并查集查找所属的类别
int find(int a){
int tem =a,t;
while(node[a]!= a){
a= node[a];
}
// 路径压缩
while(tem != a){
t = node[tem];
node[tem] = a;
tem = t;
}
return a;
}
// 并查集 合并
bool join(int a,int b){
int x,y;
bool flag = false;
x = find(a);
y = find(b);
if(x != y){
node[x]=y;
flag = true;
}
return flag;
}
int main()
{
int n,m,root,i,max,count=0;
scanf("%d%d%d",&n,&m,&root);
edge e[m];
for(i=0;i<m;i++){
scanf("%d%d%d",&(e[i].n1),&(e[i].n2),&(e[i].w));
}
sort(e,e+m);
for(i=1;i<n+1;i++){
node[i]=i;
}
for(i=0;i<m;i++){
if(join(e[i].n1,e[i].n2)){
max = e[i].w;
count++;
if(count == n){
break;
}
}
}
printf("%d",max);
return 0;
}