0w1

UVA 1395 Slim Span ( 水題最小瓶頸生成樹 )

UVa Online Judge
先將邊以邊權排序後,枚舉以哪個邊為最小值,用最小瓶頸生成樹的算法算出最小的最大值。複雜度 O( n * m lg m )。據說這題有進階版
UVa Online Judge
UVA 12275 Sensor network - 0w1

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100 + 2;
const int MAXM = MAXN * MAXN;
const int INF = 1e9;

struct Edge{
    int u, v, w;
    Edge(){}
    Edge(int _u, int _v, int _w): u(_u), v(_v), w(_w){}
    bool operator < (const Edge &oth) const{
        return w < oth.w;
    }
} es[MAXM];

int n, m;
vector<Edge> G[MAXN];

struct UnionFind{
    int fa[MAXN];
    void init(int n){
        for(int i = 0; i <= n; ++i)
            fa[i] = i;
    }
    int find(int x){ return fa[x] == x ? x : fa[x] = find( fa[x] ); }
    bool unite(int a, int b){
        int x = find( a ), y = find( b );
        if( x == y ) return false; // no changes made
        fa[x] = y; return true;
    }
} uf;

struct Kruskal{ // es => 1 - idx
    void init(){
        for(int i = 0; i <= n; ++i)
            G[i].clear();
        uf.init( n );
    }
    int solve(int k){ // starts picking from the k'th smallest
        init();
        int picked = 0;
        sort( es, es + m );
        int cur;
        for(cur = k; cur < m; ++cur){
            if( uf.unite( es[ cur ].u, es[ cur ].v ) )
                ++picked;
            if( picked == n - 1 ) break;
        }
        if( picked < n - 1 ) return INF; // impossible
        return es[ cur ].w - es[ k ].w; // maxw - minw
    }
} mst;

void solve(){
    int ans = INF;
    for(int i = 0; i < m; ++i)
        ans = min( ans, mst.solve( i ) );
    if( ans == INF ) puts("-1");
    else printf("%d\n", ans);
}

int main(){
    while( scanf("%d%d", &n, &m) == 2 && n + m ){
        for(int i = 0; i < m; ++i)
            scanf("%d%d%d", &es[i].u, &es[i].v, &es[i].w);
        solve();
    }
    return 0;
}