POJ 3522 最大边与最小边差值最小的生成树(最小生成树的性质)

本文介绍了一种基于最小生成树的算法,通过寻找最短边与最长边的最小间距来解决问题。具体步骤包括对边进行排序,并尝试每条边作为最短边构建最小生成树,最终确定最优解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

思路:

最小生成树的性质:最短边与最长边的间距,即:最长边的权值-最短边的权值 最小
所以对这个题来说,先对所有边的权值排个序,然后分别以其中的一条边作为最短边来进行最小生成树的构造,记录每个最小生成树的结果。注意,剩下的至少要有n-1条边才能构成,所以可以稍稍剪一下枝。

#include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>

using namespace std;

struct edge{
    int x,y,v;
}e[10010];

bool cmp(const edge &a,const edge &b){
    return a.v < b.v;
}

int n,m;
int node[110];

int _find(int x){
    int xx = x;
    while(node[xx] != xx){
        xx = node[xx];
    }
    int temp;
    while(x != xx){
        temp = node[x];
        node[x] = xx;
        x = temp;
    }
    return xx;
}
bool _merge(int x,int y){
    int xx = _find(x);
    int yy = _find(y);
    if(xx != yy){
        node[yy] = xx;
        return true;
    }
    return false;
}

int kruskal(int ii){
    for(int i = 1;i <= n;i++){
        node[i] = i;
    }
    int cnt = 0;
    int ans = e[ii].v;
    int ans2;
    for(int i = ii;i <= m && cnt != n-1;i++){
        if(_merge(e[i].x,e[i].y)){
            ans2 = e[i].v;
            cnt++;
        }
    }
    if(cnt != n-1)
        return 1000000;
    return ans2 - ans;
}

int main(){
    int ans = 0;
    while(scanf("%d%d",&n,&m),n||m){
        ans = 1000000;
        for(int i = 1;i <= m;i++){
            scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].v);
        }
        sort(e+1,e+1+m,cmp);
        for(int i = 1;i <= m - n + 2;i++){
            ans = min(ans,kruskal(i));
        }
        if(ans == 1000000)
            ans = -1;
        printf("%d\n",ans);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值