UVALive-3887 Slim Span (kruskal)

题目大意:定义无向图生成树的最大边与最小边的差为苗条度,找出苗条度最小的生成树的苗条度。

题目分析:先将所有边按权值从小到大排序,在连续区间[L,R]中的边如果能构成一棵生成树,那么这棵树一定有最小的苗条度。枚举所有这样的区间。

代码如下:

# include<iostream>
# include<cstdio>
# include<set>
# include<queue>
# include<cstring>
# include<algorithm>
using namespace std;
# define REP(i,s,n) for(int i=s;i<n;++i)
# define CL(a,b) memset(a,b,sizeof(a))
# define CLL(a,b,n) fill(a,a+n,b)

const int N=105;
const int INF=1<<30;
struct Edge
{
    int u,v,w;
    bool operator < (const Edge &a) const {
        return w<a.w;
    }
};
Edge e[5005];
int fa[N],n,m;

int findFa(int u)
{
    if(fa[u]!=u)
        return fa[u]=findFa(fa[u]);
    return u;
}

bool judge()
{
    int cnt=0;
    REP(i,1,n+1) if(fa[i]==i) ++cnt;
    return cnt==1;
}

int main()
{
    //freopen("UVALive-3887 Slim Span.txt","r",stdin);
    while(scanf("%d%d",&n,&m)&&(n+m))
    {
        REP(i,0,m) scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
        sort(e,e+m);
        int ans=INF;
        REP(L,0,m){
            REP(i,1,n+1) fa[i]=i;
            REP(R,L,m){
                int u=e[R].u,v=e[R].v;
                int a=findFa(u);
                int b=findFa(v);
                if(a!=b)
                    fa[a]=b;
                if(judge()){
                    ans=min(ans,e[R].w-e[L].w);
                    break;
                }
            }
        }
        if(ans==INF)
            printf("-1\n");
        else
            printf("%d\n",ans);
    }
    return 0;
}

  

时间: 2024-08-05 23:41:15

UVALive-3887 Slim Span (kruskal)的相关文章

UVA1395 Slim Span(kruskal)

题目:Slim Span UVA 1395 题意:给出一副无向有权图,求生成树中最小的苗条度(最大权值减最小权值),如果不能生成树,就输出-1: 思路:将所有的边按权值有小到大排序,然后枚举每一条边,以这条边开始利用Kruskal算法生成树,生成过程中求出权值的最大值,这个最大值减去当前枚举的边的权值就是苗条度,再动态维护一下最小苗条度就可以了. #include <iostream> #include <algorithm> #include <queue> #inc

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,.

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 

UVA 1395 - Slim Span(MST)

UVA 1395 - Slim Span 题目链接 题意:给定一些结点和边,要求出最苗条度最小的生成树,苗条度定义为:生成树中最大权的边减去最小权的边的值 思路:类似建最小生成树的算法,多一步枚举起始边即可 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 105; const int INF = 0x3f3f3f3f; int

1395 - Slim Span (最小生成树)

UVA上的题就是让人眼前一亮,不同于那些赤裸裸的生成树水题,该题稍加了变化,不是求最小生成树,而是求最苗条生成树 . 因为生成树有很多,而且每一棵生成树的最大边与最小边只差也是不确定的 .所以只能枚举所有的生成树 . 套用最小生成树模板 ,我们可以枚举生成树的起点位置,然后向后推终点位置,当n个点全部连通时,那么这棵生成树的边集就是[L,R] .因为边事先都排好序了, 那么该树的苗条值就是e[R] - e[L] . 这样从小到大枚举所有的L ,不断更新答案,就可以了 . 忍不住再说一下并查集,这

UVALIVE 3887 Slim Span

#include <map> #include <set> #include <list> #include <cmath> #include <ctime> #include <deque> #include <stack> #include <queue> #include <cctype> #include <cstdio> #include <string> #inc

UVa 1395 Slim Span (最小生成树)

题意:给定n个结点的图,求最大边的权值减去最小边的权值最小的生成树. 析:这个和最小生成树差不多,从小到大枚举左端点,对于每一个左端点,再枚举右端点,不断更新最小值.挺简单的一个题. #include <iostream> #include <cstdio> #include <algorithm> using namespace std; const int maxn = 100 + 5; const int INF = 0x3f3f3f3f; int p[maxn]

Sicily 1504:Slim Span(最小生成树)

1 #include<bits/stdc++.h> 2 using namespace std; 3 4 struct Vertex{ 5 int start, end; 6 int weight; 7 }; 8 Vertex arr[10000]; 9 int par[10000]; 10 int n, m; 11 int find(int n){ 12 while(par[n] != n){ 13 n = par[n]; 14 } 15 return n; 16 } 17 void mer

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