Slim Span
Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 7594   Accepted: 4029

Description

Given an undirected weighted graph G, you should find one of spanning trees specified as follows.

The graph G is an ordered pair (VE), where V is a set of vertices {v1v2, …, vn} and E is a set of undirected edges {e1e2, …, em}. Each edge e ∈ E has its weight w(e).

A spanning tree T is a tree (a connected subgraph without cycles) which connects all the n vertices with n − 1 edges. 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.


Figure 5: A graph G and the weights of the edges

For example, a graph G in Figure 5(a) has four vertices {v1v2v3v4} and five undirected edges {e1e2e3e4e5}. The weights of the edges are w(e1) = 3, w(e2) = 5, w(e3) = 6, w(e4) = 6, w(e5) = 7 as shown in Figure 5(b).


Figure 6: Examples of the spanning trees of G

There are several spanning trees for G. Four of them are depicted in Figure 6(a)~(d). The spanning tree Ta in Figure 6(a) has three edges whose weights are 3, 6 and 7. The largest weight is 7 and the smallest weight is 3 so that the slimness of the tree Ta is 4. The slimnesses of spanning trees TbTc and Td shown in Figure 6(b), (c) and (d) are 3, 2 and 1, respectively. You can easily see the slimness of any other spanning tree is greater than or equal to 1, thus the spanning tree Td in Figure 6(d) is one of the slimmest spanning trees whose slimness is 1.

Your job is to write a program that computes the smallest slimness.

Input

The input consists of multiple datasets, followed by a line containing two zeros separated by a space. Each dataset has the following format.

n m  
a1 b1 w1
   
am bm wm

Every input item in a dataset is a non-negative integer. Items in a line are separated by a space. n is the number of the vertices and m the number of the edges. You can assume 2 ≤ n ≤ 100 and 0 ≤ m ≤ n(n − 1)/2. ak and bk(k = 1, …, m) are positive integers less than or equal to n, which represent the two vertices vak and vbk connected by the kth edge ekwk is a positive integer less than or equal to 10000, which indicates the weight of ek. You can assume that the graph G = (VE) is simple, that is, there are no self-loops (that connect the same vertex) nor parallel edges (that are two or more edges whose both ends are the same two vertices).

Output

For each dataset, if the graph has spanning trees, the smallest slimness among them should be printed. Otherwise, −1 should be printed. An output should not contain extra characters.

Sample Input

4 5
1 2 3
1 3 5
1 4 6
2 4 6
3 4 7
4 6
1 2 10
1 3 100
1 4 90
2 3 20
2 4 80
3 4 40
2 1
1 2 1
3 0
3 1
1 2 1
3 3
1 2 2
2 3 5
1 3 6
5 10
1 2 110
1 3 120
1 4 130
1 5 120
2 3 110
2 4 120
2 5 130
3 4 120
3 5 110
4 5 120
5 10
1 2 9384
1 3 887
1 4 2778
1 5 6916
2 3 7794
2 4 8336
2 5 5387
3 4 493
3 5 6650
4 5 1422
5 8
1 2 1
2 3 100
3 4 100
4 5 100
1 5 50
2 5 50
3 5 50
4 1 150
0 0

Sample Output

1
20
0
-1
-1
1
0
1686
50

Source


copy一下MST的性质:
  • (1)切割性质:(各边边权均不相同)一条边是连接图中某非全集非空集的点集合S和其补集中所有的边的最小边,那么这条边就在最小生成树中。
  • 证明:回忆kruscal算法的过程,这条边是连接这两个集合的最小边,那么在枚举到这条边之前,这两个集合一定没有被合并
  • (2)回路性质:(各边边权均不相同)图若有回路,那么回路中的最长边一定不在最小生成树中
  • 证明:回路中至少一条边不在最少生成树中,假设最长边在最小生成树中,那么一定存在一条更小的边替代它。
  • (3)最小瓶颈生成树:使最大边权值尽量小的生成树
  • 最小生成树就是这么一棵树,因为kruscal算法的过程
  • (4)最小瓶颈路:找u到v的一条路径满足最大边权值尽量小
  • 先求最小生成树,然后u到v的路径在树上是唯一的,答案就是这条路径
  • 如果只求一次,也可以用spfa稍作变形解决

本题求最苗条的生成树

可以发现对于一个最小边的权值,它对应的MST中的最大边的权值一定是最苗条的

枚举求就可以了

//
// main.cpp
// poj3522slim
//
// Created by Candy on 9/14/16.
// Copyright © 2016 Candy. All rights reserved.
// #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=,INF=1e9;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x;
}
int n,m,ans=INF;
struct edge{
int u,v,w;
bool operator<(const edge &rhs)const{return w<rhs.w;}
}e[N*N];
int p[N];
int find(int x){return x==p[x]?x:p[x]=find(p[x]);}
int kruskal(int st){
int ans=INF,cnt=;
for(int i=;i<=n;i++) p[i]=i;
for(int i=st;i<=m;i++){
int u=e[i].u,v=e[i].v;
int x=find(u),y=find(v);
if(x!=y){
ans=e[i].w;
p[x]=y;
if(++cnt==n-) break;
}
}
if(cnt!=n-) return -;
return ans;
}
int main(int argc, const char * argv[]) {
while(cin>>n>>m){
if(n==&&m==) break;
ans=INF;
for(int i=;i<=m;i++){
e[i].u=read();e[i].v=read();e[i].w=read();
}
sort(e+,e++m);
for(int st=;st<=m-n+;st++){
int tmp=kruskal(st);
if(tmp!=-) ans=min(ans,tmp-e[st].w);
}
if(ans!=INF) printf("%d\n",ans);
else printf("-1\n");
}
return ;
}

最小生成树POJ3522 Slim Span[kruskal]的更多相关文章

  1. POJ-3522 Slim Span(最小生成树)

    Slim Span Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 8633   Accepted: 4608 Descrip ...

  2. POJ3522 Slim Span

    Slim Span Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 7462   Accepted: 3959 Descrip ...

  3. Uva1395 POJ3522 Slim Span (最小生成树)

    Description Given an undirected weighted graph G, you should find one of spanning trees specified as ...

  4. 【kruscal】【最小生成树】poj3522 Slim Span

    求一个生成树,使得最大边权和最小边权之差最小.由于数据太小,暴力枚举下界,求出相应的上界.最后取min即可. #include<cstdio> #include<algorithm& ...

  5. POJ 3522 - Slim Span - [kruskal求MST]

    题目链接:http://poj.org/problem?id=3522 Time Limit: 5000MS Memory Limit: 65536K Description Given an und ...

  6. POJ 3522 Slim Span (Kruskal枚举最小边)

    题意: 求出最小生成树中最大边与最小边差距的最小值. 分析: 排序,枚举最小边, 用最小边构造最小生成树, 没法构造了就退出 #include <stdio.h> #include < ...

  7. 最小生成树练习2(Kruskal)

    两个BUG鸣翠柳,一行代码上西天... hdu4786 Fibonacci Tree(生成树)问能否用白边和黑边构成一棵生成树,并且白边数量是斐波那契数. 题解:分别优先加入白边和黑边,求出生成树能包 ...

  8. poj 3522 Slim Span (最小生成树kruskal)

    http://poj.org/problem?id=3522 Slim Span Time Limit: 5000MS   Memory Limit: 65536K Total Submissions ...

  9. Slim Span(Kruskal)

    题目链接:http://poj.org/problem?id=3522   Slim Span Time Limit: 5000MS   Memory Limit: 65536K Total Subm ...

随机推荐

  1. JavaScript学习笔记-正则表达式(语法篇)

    正则表达式的模式规则是由一个字符系列组成的,包括所有字母和数字在内;大多数的字符(所有字母和数字)都是按字符的直接量来描述带匹配的字符;一些具有特殊语义的字符按照其特殊语义来进行匹配,有些字符需要通过 ...

  2. SAP 应用服务负载均衡的实现

         共两步,一是服务器的设置,二是客户端登陆设置.     先在SAP中使用SMLG 进行服务器分组.实例名是SAP系统中定义过的,你没法删也没改.(可能是俺不会,会的教教).我们先建一个Gro ...

  3. Urban Planning and Public Health - Reflection on Professor Webster's article in Urban Planning Forum

    1. General review. Professor Webster published this article in Urban Planning Forum, one of the top ...

  4. popover带箭头弹框

    我们先来看一下效果吧: 分析:这个带箭头的弹框其实是一个控制器,通过Modal方式展现,但跟传统模态方式效果不一样,我们一眼就能看出. Xib方式实现popover: 1.segue的时候选择Pres ...

  5. Android 沉浸式状态栏 实现方式二 ( 更简单 )

    以前写过一个沉浸式状态栏 的实现方式 Android 沉浸式状态栏 实现方式一 现在有个更为简单的实现方式 . 相关链接 http://www.apkbus.com/forum.php?mod=vie ...

  6. Android不同屏幕适配

    1.尽量使用线性布局(LinearLayout)和相对布局(RelativeLayout),不要使用绝对布局. 2.尽量使用dip和sp,不要使用px. 3.为不同的分辨率提供不同的布局文件和图片.  ...

  7. CGAffineTransformMakeRotation 实现旋转

    UIImageView *image = [[UIImageView alloc]init]; image.frame = CGRectMake(50, 50, 200, 200); image.im ...

  8. Android常用设计模式(二)

    Android常用设计模式之观察者模式 观察者设计模式在Android应用中会经常用到,模式原理类似于这样的场景: 用户订报纸,然后在报社登记,报社来统计用户(添加用户),用户也可以取消订阅,报社删除 ...

  9. 用GCD线程组与GCD信号量将异步线程转换为同步线程

    有时候我们会碰到这样子的一种情形: 同时获取两个网络请求的数据,但是网络请求是异步的,我们需要获取到两个网络请求的数据之后才能够进行下一步的操作,这个时候,就是线程组与信号量的用武之地了. #impo ...

  10. NSString 字符串替换

    NSString * oneScale=@"@ddd"; NSLog(@"%@",[oneScale stringByReplacingOccurrencesO ...