- 传送门 -
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4141
Time limit: 3.000 seconds
| Root |
|
(题面见pdf)
- 题意 -
求一棵最大边与最小边差值最小的生成树.
- 思路 -
边按权值排序, 然后直接枚举.
枚举从第 k 大的边开始插入, 然后依次插入比它大的边, 当插入的边生成了树时, 当前边和最开始插入的边的差值就可以用来更新答案了.
细节见代码.
- 代码 -
#include<cstdio>
#include<algorithm>
using namespace std;
const int N = 105;
const int INF = 1e9;
struct edge {
int x, y, v;
}W[N*N*2];
int F[N];
int n, m, ans, cnt;
bool cmp (edge a, edge b) { return a.v < b.v; }
int find(int x) { return x == F[x] ? x : F[x] = find(F[x]); }
void add(int t) {
int xf = find(W[t].x), yf = find(W[t].y);
if (xf == yf) return;
F[xf] = yf;
cnt ++;
}
int main() {
while ((scanf("%d%d", &n, &m) != EOF) && n) {
for (int i = 1; i <= m; ++i)
scanf("%d%d%d", &W[i].x, &W[i].y, &W[i].v);
sort(W + 1, W + m + 1, cmp);
ans = INF;
for (int i = 1; i <= m - n + 2; ++i) {
for (int j = 1; j <= n; ++j)
F[j] = j;
cnt = 0;
for (int j = i; j <= m; ++j) {
add(j);
if (cnt == n - 1) {
ans = min(ans, W[j].v - W[i].v);
break;
}
}
}
if (ans == INF) ans = -1;
printf("%d
", ans);
}
return 0;
}