POJ3522 Slim Span

Slim Span

Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 7462   Accepted: 3959

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

Japan 2007

kruskal求最小生成树,每次删掉可用边中最小的,然后再跑最小生成树……不断更新答案

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 const int INF=1e7;
 8 const int mxn=12000;
 9 int n,m;
10 int ans;
11 struct edge{
12     int x,y;
13     int v;
14 }e[mxn];
15 int cmp(const edge a,const edge b){
16     return a.v<b.v;
17 }
18 int fa[mxn];
19 void init(int x){
20     for(int i=1;i<=x;i++)fa[i]=i;return;
21 }
22 int find(int x){
23     if(fa[x]==x)return x;
24     return fa[x]=find(fa[x]);
25 }
26 void Kruskal(int st){
27     init(n);
28     int i,j;
29     int cnt=0;
30     for(i=st;i<=m && cnt!=n-1;i++){
31         int x=find(e[i].x);int y=find(e[i].y);
32         if(x!=y){
33             fa[x]=y;
34             cnt++;
35         }
36         if(cnt==n-1){
37             ans=min(ans,e[i].v-e[st].v);
38             return;
39         }
40     }
41     return;
42 }
43 int main(){
44     while(scanf("%d%d",&n,&m) && (n||m)){
45         ans=INF;
46         int i,j;
47         for(i=1;i<=m;i++)scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].v);
48         sort(e+1,e+m+1,cmp);
49         for(i=1;i<=m;i++)
50             Kruskal(i);
51         if(ans==INF)printf("-1\n");
52         else printf("%d\n",ans);
53     }
54     return 0;
55 }
时间: 2024-11-14 20:02:39

POJ3522 Slim Span的相关文章

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

Slim Span Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 8633   Accepted: 4608 Description Given an undirected weighted graph G, you should find one of spanning trees specified as follows. The graph G is an ordered pair (V, E), where V 

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

求一个生成树,使得最大边权和最小边权之差最小.由于数据太小,暴力枚举下界,求出相应的上界.最后取min即可. 1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 using namespace std; 5 int n,m,fa[101],rank[101]; 6 void clear(){for(int i=1;i<=n;i++) fa[i]=i; memset(rank,0,sizeof

Uva1395 POJ3522 Slim Span (最小生成树)

Description Given an undirected weighted graph G, you should find one of spanning trees specified as follows. The graph G is an ordered pair (V, E), where V is a set of vertices {v1, v2, -, vn} and E is a set of undirected edges {e1, e2, -, em}. Each

POJ 3522 ——Slim Span——————【最小生成树、最大边与最小边最小】

Slim Span Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 7102   Accepted: 3761 Description Given an undirected weighted graph G, you should find one of spanning trees specified as follows. The graph G is an ordered pair (V, E), where V 

UVA1395 Slim Span(kruskal算法)

Slim Span [PDF Link] Given an undirected weighted graph G , you should find one of spanning trees specified as follows. The graph G is an ordered pair (V, E) , where V is a set of vertices {v1, v2,..., vn} and E is a set of undirected edges {e1, e2,.

[2016-01-27][UVA][1395][D -?Slim Span]

[2016-01-27][UVA][1395][D - Slim Span] 时间:2016-01-21  11:06:30  星期四 题目编号:UVA 1395 题目大意:求所有生成树 最大边和最小边之差的最小值 分析: 想法是枚举所有边,但是分析之后发现可以不用枚举所有的树 已知krukal得到的最小生成树得到的最小生成树,最大边最小 也就是说,这个最大边,就是使得 最大边和最小边 差值最大的边 那么,只需要求每条边的对应的差值最小的最大边即可 方法: 从最小的边开始跑生成树,然后跑krus

POJ 3522 Slim Span (Kruskal +枚举 边权差最小的生成树)

Slim Span Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 6685 Accepted: 3544 Description Given an undirected weighted graph G, you should find one of spanning trees specified as follows. The graph G is an ordered pair (V, E), where V is a

【Kruskal】Slim Span

[Uva1395]Slim Span 题目略…… 试题分析:codevs1001舒适的路线上加一个判一下连通性就好,顺便把除改成减 代码: #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; inline int read(){ int x=0,f=1;char c=getchar(); for(;!isdigit(c);

UVALive-3887 Slim Span (kruskal)

题目大意:定义无向图生成树的最大边与最小边的差为苗条度,找出苗条度最小的生成树的苗条度. 题目分析:先将所有边按权值从小到大排序,在连续区间[L,R]中的边如果能构成一棵生成树,那么这棵树一定有最小的苗条度.枚举所有这样的区间. 代码如下: # include<iostream> # include<cstdio> # include<set> # include<queue> # include<cstring> # include<al