题目描述:
sample:
Input
4
5
1
1 2 3
1 3 4
1 4 5
2 3 8
3 4 2
Output
4
note:
题目分析:
本题非常绕,甚至都用上了计算机网络的知识,但是这个题和网络没关系,而且如果不看数据的话你会看不懂的,一看注释马上明白了,实际上就是要找所有的生成树,然后找生成树里面的最大边,把所有可能的生成树都找出来,把所有的最大边一比较,找出最小的那一个,这就是最大里面找最小的问题,实际上看到这个题千万别傻乎乎的找所有的生成树然后求最值,其实生成树只需要求一个,要知道我们的生成树是最小生成树,那么意味着已经是所有最小的边了,那么所有最小的边取最大值那也就是所有生成树里面最大边里的最小值,所以和上一个题一样,我们只需要再多一个变量记录最大边的值就好了
for (int i = 0; i < m; i++)
{
if (num == n - 1)
break;
if (find(e[i].u) != find(e[i].v))
{
unite(e[i].u, e[i].v);
num++;
ans=max(ans,e[i].w);
}
}
前面的最小生成树算法一模一样,在此不赘述了
int find(int x)
{
if (fa[x] == x)
return x;
return find(fa[x]);
}
void unite(int x, int y)
{
x=find(x);
y=find(y);
if (x > y)
swap(x, y);
if (x != y)
fa[y] = x;
}
struct edge
{
int u;
int v;
int w;
}e[100005];
bool cmp(edge a,edge b)
{
if(a.w<b.w)
return true;
else
return false;
}
代码如下:
#include<iostream>
#include<algorithm>
using namespace std;
int fa[50005];
int find(int x)
{
if (fa[x] == x)
return x;
return find(fa[x]);
}
void unite(int x, int y)
{
x=find(x);
y=find(y);
if (x > y)
swap(x, y);
if (x != y)
fa[y] = x;
}
struct edge
{
int u;
int v;
int w;
}e[100005];
bool cmp(edge a,edge b)
{
if(a.w<b.w)
return true;
else
return false;
}
int main()
{
int n, m, root;//吐槽一句,这个root就没用过,不知道输入来干嘛......
cin >> n >> m >> root;
for (int i = 0; i < n; i++)
{
fa[i] = i;
}
for (int i = 0; i < m; i++)
{
int u, v, w;
cin >> e[i].u>> e[i].v>>e[i].w;
}
sort(e, e + m ,cmp);
int num = 0;//记录已经保存的点
int ans = 0;//记录最小生成树的最大边
for (int i = 0; i < m; i++)
{
if (num == n - 1)
break;
if (find(e[i].u) != find(e[i].v))
{
unite(e[i].u, e[i].v);
num++;
ans=max(ans,e[i].w);
}
}
cout << ans;
return 0;
}