UVa #1395 Slim Span (例题11-2)

86 篇文章 0 订阅

这道题的目标是最大权值和最小权值的差最小,和最小生成树不太一样。


我们可以暴力枚举最小权值(放弃权值更小的边),然后求最小生成树。因为Kruscal算法按照权值顺序考虑各条边,所以一旦所有点连通,则可以计算出最大权值和最小权值的差并记录,然后continue。


Run Time: 0.079s

#define UVa  "LT11-2.1395.cpp"		//Slim Span
char fileIn[30] = UVa, fileOut[30] = UVa;

#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<iostream>

using namespace std;

//Global Variables. Reset upon Each Case!
const int maxn = 100+5, maxm = maxn*maxn;
int n, m, u[maxm], v[maxm], w[maxm], r[maxm];
int fa[maxn];           //union-find set.
/

int cmp(int a, int b) { return w[a] < w[b]; }

int find(int s) {
    int t = s;
    while(s != fa[s]) s = fa[s];
    while(fa[t] != s) {             //re-assign parent along the path
        int tmp = fa[t];
        fa[t] = s;
        t = tmp;
    }
    return s;
}

int solve() {
    int ans = -1;
    for(int L = 0; L < m; L ++) {
        for(int i = 1; i <= n; i ++) fa[i] = i;
        for(int R = L; R < m; R ++) {
            if(ans != -1 && ans <= w[r[R]] - w[r[L]]) break;        //pruning
            int e = r[R];
            int x = find(u[e]), y = find(v[e]);
            if(x != y) {                                    //not in same connceted block, add it to connected block.
                fa[x] = y;
                for(int i = 2; i <= n; i ++)                //check connected blocks
                    if(find(i) != find(i-1))
                        goto EXIT;
                if(ans == -1) ans = w[r[R]] - w[r[L]];
                else ans = min(ans, w[r[R]] - w[r[L]]);
                break;
                EXIT: continue;
            }
        }
    }
    return ans;
}

int main() {
    while(scanf("%d%d", &n, &m) && n) {
        for(int i = 0; i < m; i ++) {
            scanf("%d%d%d", &u[i], &v[i], &w[i]);
            r[i] = i;
        }
        sort(r, r+m, cmp);
        cout<<solve()<<endl;
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值