uva1395
2016-04-17 11:27
281 查看
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=41567
/* 考察点:kruskal算法生成最小生成树 题目实现步骤: 1:把边权值从大到小排列,使用kruskal算法生成最小树 2:假定最小树中的最小边为min,最大边为max,则这棵生成树包含的边集合为(min, max) 3:所以苗条度为max - min 4:但这样的苗条度不一定最小,所以对整张图的边的集合,枚举min,然后从min开始kruskal算法 */ #include <iostream> #include <cstdio> #include <algorithm> #include <vector> using namespace std; const int maxn = 5000 +5; const int INF = 999999; int n, m, p[maxn], ch[maxn]; struct Side { int u, v, val; } sides[maxn]; bool cmp(const Side& Side1, const Side& Side2) { return Side1.val < Side2.val; } int UFind(int u) { return p[u] == u ? u : UFind(p[u]); } int solve() { //(L,R) int slimness = INF; for(int dex = 0; dex < m; dex++) { //外围枚举L int sideNum = 0; for(int i = 1; i <= n; i++) { //并查集初始化,注意节点编号从1开始 p[i] = i; } for(int i = dex; i < m; i++) { int u = UFind(sides[i].u), v = UFind(sides[i].v); if(u != v) { p[u] = v; if(++sideNum == n - 1) {slimness = min(sides[i].val - sides[dex].val, slimness); break;} } } } if(slimness == INF) slimness = -1; return slimness; } int main() { //freopen("input.txt", "r", stdin); while(scanf("%d%d", &n, &m) == 2 && n) { for(int i = 0; i < m; i++) scanf("%d%d%d", &sides[i].u, &sides[i].v, &sides[i].val); sort(sides, sides + m, cmp); if (m < n - 1) printf("-1\n"); else printf("%d\n", solve()); } return 0; }
相关文章推荐
- PHP字符集操作
- 学习进度条(七)
- sdsdsd
- 源文件名和public 类名
- 属性选择器
- hash函数
- IOS编程info.list文件参数作用
- IOS编程info.list文件参数作用
- block实现原理?
- 欢迎使用CSDN-markdown编辑器
- hdu 2037 今年暑假不AC
- ALTER TABLE 语句
- 2014年互联网公司职级,薪资表
- sqlserver 创建用户仅仅能訪问指定视图
- 结对编程之Fault、Error、Failure
- Hibernate一对一单向外键关联
- 06-图2 Saving James Bond - Easy Version (25分)
- LeetCode——042
- POJ 1015 动态规划
- VMware 虚拟机和 Macintosh 键盘对应关系表