UVa--1395 Slim Span(生成树)

来源:互联网 发布:删除微信应用数据内存 编辑:程序博客网 时间:2024/05/29 18:50

题意

给定带权无向图 G,定义:

The slimness of a spanning tree T is defined as the difference between the largest weight and the smallest weight among the n−1 edges of T.

求 slimness 尽可能小的生成树。

题解

把边按权值从小到大排序,枚举每一个边的区间,因为对于一个连续的边集区间[L,R],如果这些边能够使图连通,则一定存在slimness最大为 W[R]W[L] 的生成树。
0m 枚举 L,对每一个 L,从 Lm 枚举 R,同时用并查集判断此时图是否连通,如果连通,更新最小值,换下一个 L 继续枚举。

#include <bits/stdc++.h>using namespace std;const int maxn = 100 + 5;const int maxe = 5000;const int inf  = 1 << 30;int  p[maxn];int  u[maxe], v[maxe], w[maxe], r[maxe];int  n, m;int  find(int x) { return x == p[x] ? x : p[x] = find(p[x]); }int  cmp(int i, int j) { return w[i] < w[j]; }void initUFS() { for(int i = 1; i <= n; ++i) p[i] = i; }void solve(){    int ans = inf;    for(int i = 0; i < m; ++i)    {        initUFS();        int cnt = n;        for(int j = i; j < m; ++j)        {            int R = r[j];                   //第j条边在排序前的下标            int x = find(u[R]), y = find(v[R]);            if(x != y)            {                p[x] = y;                if(--cnt == 1){             //连通                    ans = min(ans, w[R] - w[r[i]]);                    break;                }            }        }    }    if(ans == inf) ans = -1;    cout << ans << endl;}int main(){    #ifdef LOCAL    freopen("data.in", "r", stdin);    #endif // LOCAL    ios::sync_with_stdio(false);    while(cin >> n >> m && n)    {        for(int i = 0; i < m; ++i)        {            r[i] = i;                       //初始化边序号            cin >> u[i] >> v[i] >> w[i];        }        sort(r, r + m, cmp);        solve();    }}
0 0
原创粉丝点击