[POJ2236]Wireless Network(并查集)

题目大意

几天前做的一道题,复习一下, 首先输入几个点的坐标 ,然后修一个就和其他修好的作比较看看能否联系起来。然后S两个机器,看这两个两个机器能不能联系起来。

思路

并查集,一共有两种操作,一个是O,这是一个并的操作,首先O一个然后遍历其他的机器,如果这个机器开了并且距离小于等于指定值。那好,把这两个点合并。
同样,S操作就是检查两个机器是否已经连起来了。

代码

#include <cstdio>
#include <cmath>
#include <cstring>
#define MAXN 1000 + 10

int n, d;

struct node {
    int x, y;
};

node cache[MAXN];
int pre[MAXN];
bool is_ok[MAXN];

bool contact(node & a, node & b) {
    return sqrt(pow(a.x - b.x, 2) + pow(a.y - b.y, 2)) <= d;
}

int find(int x) {        
    int r = x;
    while(pre[r] != r) {
        r = pre[r];
    }
    int i = x, j;
    while(i != r) {
        j = pre[i];
        pre[i] = r;
        i = j;
    }
    return r;
}

void join(int x, int y) {
    int fx = find(x);
    int fy = find(y);
    if (fx != fy) {
        pre[fx] = fy;
    }
}

int main() {
    //freopen("input.txt", "r", stdin);
    char op;
    scanf("%d%d", &n, &d);
    for(int i = 1; i <= n; i++) {
        scanf("%d%d", &cache[i].x, &cache[i].y);
    }
    for(int i = 1; i <= n; i++)
        pre[i] = i;
    memset(is_ok, false, sizeof(is_ok));
    while(scanf("%c", &op) != EOF) {
        if (op == 'O') {
            int t;
            scanf("%d", &t);
            for(int i = 1; i <= n; i++) {
                if (i != t && is_ok[i]) {
                    if (contact(cache[i], cache[t])) join(i, t);
                }
            }
            is_ok[t] = true;
        }
        else if (op == 'S') {
            int a, b;
            scanf("%d%d", &a, &b);
            if (find(a) == find(b)) printf("SUCCESS\n");
            else printf("FAIL\n");
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sunmaoxiang/article/details/80767549
今日推荐