UVa 1395 - Slim Span --生成树入门题

题目链接
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4141
问题的意思是叫你找到一颗生成树,生成树的值定义为权重最大的一条边 Wmax 减去权重最小的一条边 Wmin ,使生成树的值最小,输入和输出看原题,顶点个数 n<=100 ,边 m<(n1)n/2 可以估算出 m<5000 .
分析
由于这道题的边数不是很大,可以用枚举的方式固定一条最小边,再找权重比他大的边用Kruskal的算法构造生成树。
简单分析一下复杂度。最小边最多小于5000种,每种情况最多找99条边。也就是说在 O(105) 界内能够找到
代码

#include<cstdio>
#include<algorithm>
#include<cstring>
#define INF 0x3f3f3f3f
#define maxe 50010
#define maxn 109
using namespace std;

int nv,ne;
struct Edge{
    int u,v,w;
    bool operator<(Edge& o)
    {
        return w<o.w;
    }
}edge[maxe];

//set
int p[maxn];

int find(int a)
{
    return p[a] ==a? a:p[a] = find(p[a]); 
}

void union_set(int x,int y)
{
    x = find(x);
    y = find(y);
    if(x!=y)
        p[x] = y;
}



int main()
{
    //freopen("H:\\c++\\file\\stdin.txt","r",stdin);

    while(scanf("%d %d",&nv,&ne)&&nv)
    {
        for(int i=0 ; i<ne ; ++i)scanf("%d %d %d",&edge[i].u,&edge[i].v,&edge[i].w);
        if(ne<nv-1){
            printf("-1\n");
            continue;
        }

        sort(edge,edge+ne);


        int ans = INF;
        for(int l = ne - nv+1 ; l>=0 ;--l)
        {
            int max = l;
            int cnt=1;
            //生成树 
            for(int i=1 ; i<=nv ; ++i )p[i] = i;
            union_set(edge[l].u,edge[l].v);
            while(cnt<nv-1)
            {
                max++;
                if(max>=ne){
                    break;
                }else
                {
                    int x = find(edge[max].u);
                    int y = find(edge[max].v);
                    if(x!=y)
                    {
                        cnt++;
                        union_set(x,y);
                    }
                }

            }
            if(cnt==nv-1&&ans>edge[max].w-edge[l].w)ans= edge[max].w-edge[l].w;
        }
        if(ans == INF)printf("-1\n");
        else printf("%d\n",ans);
    }


    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值