HDU 1875 暢通工程再續 (Prim)

題目連接:HDU 1875php

Problem Description

相信你們都據說一個「百島湖」的地方吧,百島湖的居民生活在不一樣的小島中,當他們想去其餘的小島時都要經過劃小船來實現。如今政府決定大力發展百島湖,發展首先要解決的問題固然是交通問題,政府決定實現百島湖的全暢通!通過考察小組RPRush對百島湖的狀況充分了解後,決定在符合條件的小島間建上橋,所謂符合條件,就是2個小島之間的距離不能小於10米,也不能大於1000米。固然,爲了節省資金,只要求實現任意2個小島之間有路通便可。其中橋的價格爲 100元/米。c++

Input

輸入包括多組數據。輸入首先包括一個整數T(T <= 200),表明有T組數據。markdown

每組數據首先是一個整數C(C <= 100),表明小島的個數,接下來是C組座標,表明每一個小島的座標,這些座標都是 0 <= x, y <= 1000的整數。spa

Output

每組輸入數據輸出一行,表明建橋的最小花費,結果保留一位小數。若是沒法實現工程以達到所有暢通,輸出」oh!」.code

Sample Input

2
2
10 10
20 20
3
1 1
2 2
1000 1000

Sample Output

1414.2
oh!

Author

8600ip

Source

2008浙大研究生複試熱身賽(2)——全真模擬get

Solution

題意

給定 \(n\) 個小島的座標,要在小島間建橋,聯通全部的島。建橋的條件是兩個小島間距離爲 \([10, 1000]\),建橋的價格是 \(100\) 元/米,求最小造價。input

思路

最小生成樹裸題。it

只有小島距離在 \([10, 1000]\) 才建邊。io

注意 \(double\)

Code

#include <bits/stdc++.h>
using namespace std;
typedef double db;
const int N = 110;
const db inf = 1e18;
typedef pair<db, int> P;
int n, m;

struct Point {
    db x, y;
};

struct Edge {
    int to;
    db w;
    Edge(int to, db w): to(to), w(w) {}
};
Point p[N];
vector<Edge> G[N];
db d[N];
int v[N];

void init() {
    for(int i = 0; i < N; ++i) {
        G[i].clear();
    }
}

void add(int x, int y, db z) {
    G[x].push_back(Edge(y, z));
}

db prim(int s) {
    priority_queue<P, vector<P>, greater<P>> q;
    for(int i = 0; i <= n; ++i) {
        d[i] = inf;
    }
    memset(v, 0, sizeof(v));
    db ans = 0;
    d[s] = 0;
    q.push(P(0, s));
    while(q.size()) {
        P p = q.top(); q.pop();
        int x = p.second;
        if(v[x]) continue;
        v[x] = 1;
        ans += d[x];
        for(int i = 0; i < G[x].size(); ++i) {
            Edge e = G[x][i];
            if (d[e.to] > e.w && !v[e.to]) {
                d[e.to] = e.w;
                q.push(P(d[e.to], e.to));
            }
        }
    }
    return ans;
}

db dis(Point a, Point b) {
    return sqrt(pow(a.x - b.x, 2) + pow(a.y - b.y, 2));
}

int main() {
    int T;
    scanf("%d", &T);
    while(T--) {
        init();
        scanf("%d", &n);
        for(int i = 1; i <= n; ++i) {
            scanf("%lf%lf", &p[i].x, &p[i].y);
        }
        for(int i = 1; i <= n; ++i) {
            for(int j = i + 1; j <= n; ++j) {
                db tmp = dis(p[i], p[j]);
                if(tmp >= 10 && tmp <= 1000) {
                    add(i, j, tmp);
                    add(j, i, tmp);
                }
            }
        }
        db ans = prim(1) * 100;
        if(ans == 0) printf("oh!\n");
        else printf("%.1lf\n", ans);
    }
    return 0;
}
相關文章
相關標籤/搜索