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 (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

题意:求一个图的生成树中,边最大权值和最小权值差的最小值。

思路:由于数据范围较少,可以选择暴力,生成不同的生成树,之后记录下最小值即可

AC代码:

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <queue>
#include <map>
#include <algorithm>
#include <iostream>
using namespace std;
#define inf 0x3f3f3f3f

const int maxn=105;

int par[maxn];

struct node{
    int x,y,w;
} edge[10005];;

bool cmp(node a,node b){
    return a.w<b.w;
}

int init(int n){
    for(int i=1;i<=n;i++){
        par[i]=i;
    }
}

int find(int x){
    if(par[x]==x){
        return x;
    }else{
        return par[x]=find(par[x]);
    }
}

int unite(int x,int y){
    x=find(x);
    y=find(y);
    if(x==y){
        return 0;
    }else{
        par[x]=y;
        return 1;
    }
}

int main(){
    int n,m;
    while(scanf("%d%d",&n,&m)==2&&!(!n&&!m)){
        int mins=inf;
        for(int i=0;i<m;i++){
            scanf("%d%d%d",&edge[i].x,&edge[i].y,&edge[i].w);
        }
        sort(edge,edge+m,cmp);

        for(int i=0;i<m;i++){
            int cnt=0;
            init(n);
            for(int j=i;j<m;j++){
                if(unite(edge[j].x,edge[j].y)){
                    cnt++;
                    if(cnt==n-1){
                        int tmp=edge[j].w-edge[i].w;
                        if(mins>tmp)mins=tmp;
                        break;
                    }
                }
            }
        }
        if(mins==inf)printf("-1\n");
        else printf("%d\n",mins);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/87hbteo/p/8947655.html

时间: 2024-08-01 21:38:14

Uva1395 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 

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 (V, E), where V 

uva1395 - Slim Span(最小生成树)

先判断是不是连通图,不是就输出-1. 否则,把边排序,从最小的边开始枚举最小生成树里的最短边,对每个最短边用Kruskal算法找出最大边. 或者也可以不先判断连通图,而是在枚举之后如果ans还是INF,说明就没有,就输出-1. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<cmath>

【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

POJ 3522 Slim Span 最小生成树,暴力 难度:0

kruskal思想,排序后暴力枚举从任意边开始能够组成的最小生成树 #include <cstdio> #include <algorithm> using namespace std; const int maxn = 101; const int maxe = maxn * maxn / 2; struct edge{ int f,t,c; bool operator <(edge e2)const { return c<e2.c; } }e[maxe]; int

POJ 3522 Slim Span(最小生成树)

题意:给定一个n个点m条边的无向图,找一颗苗条度(最大边减最小边)最小的生成树. 思路:假设苗条度最小的这棵树的最小边为a,若要使苗条度最小,答案一定是以a为最小边的一颗最小生成树,所以可以考虑枚举最小边,计算出苗条度并更新答案. #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<algorithm

UVA 1395 Slim Span (最小生成树,MST,kruscal)

题意:给一个图,找一棵生成树,其满足:最大权-最小权=最小.简单图,不一定连通,权值可能全相同. 思路:点数量不大.根据kruscal每次挑选的是最小权值的边,那么苗条度一定也是最小.但是生成树有多棵,苗条度自然也有多个,穷举下所有生成树,就知道了结果了.根据“只要起始边不同,生成树必定不同”来穷举起始边. 又发现一可能的坑!!我以为LONG_MAX就是int的正最大值,也就是2147483647=2^31-1,在我的机器上也许如此,在OJ上不一定了,用LONG_MAX转int会不同,得注意.

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 

POJ 3522 Slim Span【枚举+克鲁斯卡尔求最小生成树】

Slim Span Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 7365 Accepted: 3909 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