UVA-1395 - Slim Span(kruskal)

题意:求生成树,并且生成树的最大边减最小边的值最小.

分析:根据最小瓶颈生成树可知,使用kruscal算法枚举最小边即可

// File Name: 1395.cpp
// Author: Zlbing
// Created Time: 2013/4/20 13:00:15

#include<iostream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<stack>
#include<cmath>
#include<queue>
using namespace std;
#define CL(x,v); memset(x,v,sizeof(x));
#define INF 0x3f3f3f3f
#define LL long long
#define REP(i,r,n) for(int i=r;i<=n;i++)
#define RREP(i,n,r) for(int i=n;i>=r;i--)
const int MAXN=105;

int n,m;
struct Edge{
    int u,v,cost;
    bool operator <(const Edge& a)const{
        return cost>a.cost;
    }
};
vector<Edge> edges;
int F[MAXN];
int find(int x)
{
    return x==F[x]?x:F[x]=find(F[x]);
}
int kruskal(int k)
{
    for(int i=0;i<=n;i++)F[i]=i;
    int cnt=0;
    int minn=INF,maxn=0;
    for(int i=k;i<m;i++)
    {
        Edge e=edges[i];
        int v=e.v;
        int u=e.u;
        int fu=find(u);
        int fv=find(v);
        if(fu!=fv)
        {
            cnt++;
            F[fu]=fv;
            minn=min(e.cost,minn);
            maxn=max(e.cost,maxn);
        }
    }
    if(cnt!=n-1)
        return -1;
    else return maxn-minn;
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        if(n==0&&m==0)break;
        edges.clear();
        REP(i,1,m)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            edges.push_back((Edge){a,b,c});
        }
        sort(edges.begin(),edges.end());
        int ans=INF;
        REP(i,0,m)
        {
            int t=kruskal(i);
            if(t==-1)break;
            ans=min(ans,t);
        }
        if(ans==INF)printf("%d\n",-1);
        else printf("%d\n",ans);
    }
    return 0;
}

 

posted @ 2013-04-20 13:37  z.arbitrary  阅读(451)  评论(0编辑  收藏  举报