UVa--1395 Slim Span(生成树)
2016-02-22 22:08
357 查看
题意
给定带权无向图 G,定义:The slimness of a spanning tree T is defined as the difference between the largest weight and the smallest weight among the n−1 edges of T.
求 slimness 尽可能小的生成树。
题解
把边按权值从小到大排序,枚举每一个边的区间,因为对于一个连续的边集区间[L,R],如果这些边能够使图连通,则一定存在slimness最大为 W[R]−W[L] 的生成树。从 0…m 枚举 L,对每一个 L,从 L…m 枚举 R,同时用并查集判断此时图是否连通,如果连通,更新最小值,换下一个 L 继续枚举。
#include <bits/stdc++.h> using namespace std; const int maxn = 100 + 5; const int maxe = 5000; const int inf = 1 << 30; int p[maxn]; int u[maxe], v[maxe], w[maxe], r[maxe]; int n, m; int find(int x) { return x == p[x] ? x : p[x] = find(p[x]); } int cmp(int i, int j) { return w[i] < w[j]; } void initUFS() { for(int i = 1; i <= n; ++i) p[i] = i; } void solve() { int ans = inf; for(int i = 0; i < m; ++i) { initUFS(); int cnt = n; for(int j = i; j < m; ++j) { int R = r[j]; //第j条边在排序前的下标 int x = find(u[R]), y = find(v[R]); if(x != y) { p[x] = y; if(--cnt == 1){ //连通 ans = min(ans, w[R] - w[r[i]]); break; } } } } if(ans == inf) ans = -1; cout << ans << endl; } int main() { #ifdef LOCAL freopen("data.in", "r", stdin); #endif // LOCAL ios::sync_with_stdio(false); while(cin >> n >> m && n) { for(int i = 0; i < m; ++i) { r[i] = i; //初始化边序号 cin >> u[i] >> v[i] >> w[i]; } sort(r, r + m, cmp); solve(); } }
相关文章推荐
- PHP超牛逼无限极分类生成树方法
- 生成树配置
- 详解生成树协议STP/RSTP
- STP/RSTP/MSTP经典分析与对比
- 1.10055 - Hashmat the brave warrior
- 2.10071 - Back to High School Physics
- 3.458 - The Decoder
- 4.694 - The Collatz Sequence
- 6.494 - Kindergarten Counting Game
- 7.490 - Rotating Sentences
- 8.414 - Machined Surfaces
- 9.488 - Triangle Wave
- A.457 - Linear Cellular Automata
- B.489 - Hangman Judge
- C.445 - Marvelous Mazes
- 1.10494 - If We Were a Child Again
- 2.424 - Integer Inquiry
- 3.10250 - The Other Two Trees
- 5.465 - Overflow
- 6.113 - Power of Cryptography