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

来源:互联网 发布:大数据 普惠金融 论文 编辑:程序博客网 时间:2024/05/17 23:20

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


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


Run Time: 0.079s

#define UVa  "LT11-2.1395.cpp"//Slim Spanchar 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
原创粉丝点击