题目大意:
只有一个测例,一个无向图有N个点(2 ≤ N ≤ 2,000)和M条边(1 ≤ M ≤ 10,000),并给出M条边的信息"x y l",表示连接该边的两个端点的编号为x和y,长度为l(l ≤ 10^9),并且点的编号为1 ~ N,现在有个人要从其中一个点到其它所有点访问,要求其途中经过的最大边最小,并且为了达到该目的边可以重复走,要求输出该最大边的最小值。
思路:即求最小生成树的最大边即可,用Kurskal,也可避免重边,但就是复杂度比Prim略高。
代码:
/*
* Problem ID : POJ 2395 Out of Hay
* Author : Lirx.t.Una
* Language : C++
* Run Time : 204 ms
* Run Memory : 320 KB
*/
#include <algorithm>
#include <iostream>
#include <cstdio>
#define MAXN 2000
#define MAXM 10000
using namespace std;
struct Arc {
short u, v;
int len;
friend istream &
operator>>(istream &is, Arc &arc) {
is >> arc.u >> arc.v >> arc.len;
return is;
}
bool
operator<(const Arc &oth)
const {
return len < oth.len;
}
};
Arc arc[MAXM];
short fath[MAXN + 1];
int
find(int x) {
return x == fath[x] ? x : ( fath[x] = find( fath[x] ) );
}
int
kruskal( int n, int m ) {
int fu, fv;
int i;
n--;
for ( i = 0; i < m; i++ ) {
fu = find( arc[i].u );
fv = find( arc[i].v );
if ( fu == fv ) continue;
if ( !(--n) ) return arc[i].len;
fath[fu] = fv;
}
return -1;
}
int
main() {
int n, m;
int i;
scanf("%d%d", &n, &m);
for ( i = 1; i <= n; i++ ) fath[i] = i;
for ( i = 0; i < m; i++ ) cin >> arc[i];
sort(arc, arc + m);
printf("%d\n", kruskal( n, m ));
return 0;
}