POJ 2236:Wireless Network(並查集)

題意:
input:
第一行輸入兩個數 n, d,n代表接下來輸入的城市(1~n)的座標的數目,d表示相互連接的兩個城市之間的最大距離不能超過d。
從(n+1)行開始, 若輸入第一個字符是 ‘O’ ,那麼後面跟一個數字 x, 表示 x城市 的電腦被修復(i.e 可以連通其他的電腦)。
output:
hint:只要 a 和 b 城市在同一個集合中(不管經過幾個城市),那麼 城市a 和 城市b 就是連通的。
若輸入第一個字符是 ‘S’, 那麼後面跟兩個字符 x1, x2 若 城市x1, x2 在同一個集合中, 那麼說明可以連通, 輸出"SUCCESS"。
反之, 輸出 "FAIL‘’。

LEARN:判斷兩個點 a, b 是否屬於一個集合可以通過 a 和 b 的根節點是不是同一個來實現 if (判斷根節點(a) == 判斷根節點(b))

#include <iostream>
#include <cstring>
#include <cmath>
#include <set>

using namespace std;

int n, d, parent[1010], work[1010];
int x1, x2;
char c;
struct node {
    int x, y;
}record[1010];

void ini() {
    for (int i = 1; i <= n; i++) {
        parent[i] = i;
    }
    return;
}
int findroot(int x) {
    int r = x;
    while(parent[r] != r) {
        r = parent[r];
    }
    return r;
}
void uni(int a, int b) {
    int aa = findroot(a);
    int bb = findroot(b);
    if(aa != bb) {
        parent[aa] = bb;
    }
}
double caldis(int x1, int y1, int x2, int y2) {
    return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}

int main() {
    ios::sync_with_stdio(false);
    cin >> n >> d;
    ini();
    memset(work, 0, sizeof(work));
    for (int i = 1; i <= n; i++) {
        cin >> record[i].x >> record[i].y;
    }

    while(cin >> c) {
        if(c == 'O') {
            cin >> x1;
            work[x1] = 1;
            for (int i = 1; i <= n; i++) {
                if(i != x1 && work[i] == 1 && caldis(record[x1].x, record[x1].y, record[i].x, record[i].y) <= d) {
                    uni(x1, i);
                }
            }
        }
        else if (c == 'S') {
            cin >> x1 >> x2;
            if (findroot(x1) == findroot(x2)) { //判斷是否在同一個集合中(i.e 連通)
                cout << "SUCCESS" << endl;
            }
            else {
                cout << "FAIL" << endl;
            }
        }
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章