0w1

UVA 10369 Arctic Network ( 水題最小瓶頸生成樹 )

UVa Online Judge
取到排序後第 p - s + 1個最小的就可以了。

#include <bits/stdc++.h>
using namespace std;
const int MAXS = 100 + 2;
const int MAXP = 500 + 2;
const int MAXM = MAXP * MAXP / 2;

int n, m;

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

struct UnionFind{
    int fa[MAXP];
    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;
        fa[x] = y; return true;
    }
} uf;

int s, p;
int x[MAXP], y[MAXP];

struct Kruskal{
    void init(){
        uf.init( p );
        sort( es, es + m );
    }
    double solve(){
        int picked = 0;
        double res;
        for(int i = 0; i < m; ++i){
            if( uf.unite( es[i].u, es[i].v ) ){
                res = es[i].w;
                if( ++picked == p - s ) break;
            }
        }
        assert( picked == p - s );
        return res;
    }
} mst;

double euDis(int a, int b){
    double sqrx = (double)( x[ a ] - x[ b ] ) * ( x[ a ] - x[ b ] );
    double sqry = (double)( y[ a ] - y[ b ] ) * ( y[ a ] - y[ b ] );
    return sqrt( sqrx + sqry );
}

void makeEdge(){
    m = 0;
    for(int i = 0; i < p; ++i)
        for(int j = i + 1; j < p; ++j)
            es[ m++ ] = Edge( i, j, euDis( i, j ) );
}

void solve(){
    makeEdge();
    mst.init();
    printf("%.2lf\n", mst.solve());
}

int main(){
    int T; scanf("%d", &T);
    while( T-- ){
        scanf("%d%d", &s, &p);
        for(int i = 0; i < p; ++i)
            scanf("%d%d", &x[i], &y[i]);
        solve();
    }
    return 0;
}