题目
Example Input
4
5
1
1 2 3
1 3 4
1 4 5
2 3 8
3 4 2
Output
4
样例说明
思路:
该题要求解的是所给图的一棵生成树,该生成树权值最大的边的权值在该图所有的生成树中要最小,即寻找该图的最小瓶颈生成树。
根据最小生成树的性质,最小生成树一定是瓶颈生成树,而瓶颈生成树不一定是最小生成树。该题就可以转化为寻找给定图结构的最小生成树的最大边的权值。
采用Kruskal算法,在每次选中一条边时,将其权值与当前记录的最大权值进行比较,若大于当前最大权值,则更新记录。当n-1条边取满时,此时记录的权值,即为答案。
代码:
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 50005;
const int M = 100005;
int par[N];
int n,m, tot;
struct edge
{
int u, v, w;
bool operator<(const edge &e)const
{
return w < e.w;
}
}es[M];
void init(int n)
{
for (int i = 0; i <= n; i++)
par[i] = i;
}
int find(int x)
{
if (par[x] == x)
return x;
else
return par[x] = find(par[x]);
}
bool unite(int x, int y)
{
x = find(x), y = find(y);
if (x == y)
return false;
par[x] = y;
return true;
}
int kruskal()
{
init(n);
sort(es+1, es + m + 1);
int cnt = 0, ans = 0;
for(int i=1;i<=m;i++)
if (unite(es[i].u, es[i].v))
{
ans = max(ans,es[i].w);
if (++cnt == n-1)
return ans;
}
return -1;
}
int main()
{
scanf("%d%d%d", &n, &m, &tot);
for (int i = 1; i <= m; i++)
scanf("%d%d%d", &es[i].u, &es[i].v, &es[i].w);
printf("%d\n", kruskal());
return 0;
}