UVA1395 Slim Span 解题报告
题目链接
https://vjudge.net/problem/UVA-1395
题目大意
给出一个n(n≤100)结点的图,求苗条度(最大边减最小边的值)尽量小的生成树。
解题思路
将边按照权值从小到大排序之后,如果一个连续边集[l, r]中的边可以使得n个点全部联通,则一定存在一个苗条度不大于e[r].w - e[l].w的生成树,枚举l和r
代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
const int maxn = 1e4 + 10;
const int INF = 0x7fffffff;
const int mod = 1e9 + 7;
struct Edge {int u, v, w;bool operator < (Edge &other) const {return w < other.w;}
} e[maxn];
int fa[maxn];
int n, m;void init() {for (int i = 0; i < maxn; i++) {fa[i] = i;}
}int findRoot(int x) {if (x == fa[x])return x;return fa[x] = findRoot(fa[x]);
}void solve() {while (cin >> n >> m, n != 0) {for (int i = 0; i < m; i++) {cin >> e[i].u >> e[i].v >> e[i].w;}if (m == 0) {cout << -1 << endl;continue;}sort(e, e + m);// 将边按照权值从小到大排序之后,如果一个连续边集[l, r]中的边可以使得n个点全部联通,则一定存在一个苗条度不大于e[r].w - e[l].w的生成树,枚举l和rint ans = INF;for (int l = 0; l < m; l++) {init();int cnt = 0;for (int r = l; r < m; r++) {int faA = findRoot(e[r].u);int faB = findRoot(e[r].v);if (faA != faB) {fa[faA] = faB;cnt++;if (cnt == n - 1) {ans = min(ans, e[r].w - e[l].w);break;}}}}if (ans < INF)cout << ans << "\n";elsecout << -1 << "\n";}
}int main() {freopen("in.txt", "r", stdin);ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cout << fixed;cout.precision(18);int Case = 1;// cin >> Case;while (Case--)solve();return 0;
}