uva1395 - Slim Span(最小生成树)

先判断是不是连通图,不是就输出-1。

否则,把边排序,从最小的边开始枚举最小生成树里的最短边,对每个最短边用Kruskal算法找出最大边。

或者也可以不先判断连通图,而是在枚举之后如果ans还是INF,说明就没有,就输出-1.

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<stack>
#include<queue>
#include<cctype>
#include<sstream>
using namespace std;
#define pii pair<int,int>
#define LL long long int
const int eps=1e-8;
const int INF=1000000000;
const int maxn=100+10;
int n,m,a,b;
int p[maxn],used[maxn];
struct Edge
{
    int u,v,w;
}e[10000];
vector<int>vv[maxn];
bool cmp(const Edge& e1,const Edge& e2);
void ini();
int f(int x);
void dfs(int t);
int main()
{
    //freopen("in10.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    while(scanf("%d%d",&n,&m)==2)
    {
        if(n==0&&m==0) break;
        ini();
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&a,&b,&e[i].w);
            e[i].u=a;   e[i].v=b;
            vv[a].push_back(b);
            vv[b].push_back(a);
        }
        dfs(1);
        bool lian=true;
        for(int i=1;i<=n;i++)
        {
            if(used[i]==0)
            {
                lian=false;
                break;
            }
        }
        if(lian==false) puts("-1");//不是连通图,输出-1
        else
        {
           sort(e+1,e+m+1,cmp);
           if(m<n)
           {
               printf("%d\n",e[m].w-e[1].w);
           }
           else
           {
               int ans=INF;
               for(int i=1;i<=m;i++)
               {
                   for(int k=1;k<=n;k++) p[k]=k;
                   int num=0,ans_t;
                   for(int j=i;j<=m;j++)
                   {
                       int x=f(e[j].u);
                       int y=f(e[j].v);
                       if(x!=y){num++; p[x]=y; ans_t=e[j].w;}
                   }
                   if(num==n-1)
                   {
                       ans=min(ans,ans_t-e[i].w);
                   }
               }
               printf("%d\n",ans);
           }
        }
    }
    //fclose(stdin);
    //fclose(stdout);
    return 0;
}
bool cmp(const Edge& e1,const Edge& e2)
{
    return e1.w<e2.w;
}
void ini()
{
    for(int i=0;i<=n;i++)
    {
        vv[i].clear();
    }
    memset(used,0,sizeof(used));
}
int f(int x)
{
    return x==p[x]?x:p[x]=f(p[x]);
}
void dfs(int t)
{
    used[t]=1;//记得进来以后要先标记上
    int s=vv[t].size();
    for(int i=0;i<s;i++)
    {
        int q=vv[t][i];
        if(used[q]==0)
        {
            dfs(q);
        }
    }
}
时间: 2024-08-24 19:43:12

uva1395 - Slim Span(最小生成树)的相关文章

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

UVA1395 Slim Span(枚举最小生成树)

题意: 求最小生成树中,最大的边减去最小的边 最小值. 看了题解发现真简单=_= 将每条边进行从小到大排序,然后从最小到大一次枚举最小生成树,当构成生成树的时候,更新最小值 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 const int INF = 0x3f3f3f3f; 7 con

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

一道简单的图论题(并查集+Kruskal)求一个图的的生成树,要求最大边减最小边之差最小,输出权值之差,如果没有,输出-1要求权值差最小,所以首先将边按权值排序,枚举最小边,对于每个最小边从小到大枚举最大边用并查集判断是否连通,如果可以生成树更新ans 1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<vector> 5 using namespace std; 6

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

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

【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);

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