POJ2236--Wireless Network

题目大意:ACM公司,有n台电脑损坏了,现在可以进行两种操作,O表示修复一台电脑,S表示查询这两台电脑之间是否可以相连通,相连通的条件有两个,满足一个即可,一、这两台电脑之间距离小于等于d,二、这两台电脑可以通过其他电脑相互达到。

 

分析:用并查集维护可以联通的电脑,当修好一台电脑后,遍历一遍已修好的电脑,如果距离小于等于d,就加入并查集中。这样查询的时候,只要判断两台电脑是否在一个并查集即可。


代码:

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;

struct dot{
    int x, y;
};
dot a[1111];
int n, f[1111];
double d;
int repaired[1111];

int Find(int k) {
    return f[k] == k ? k : f[k] = Find(f[k]);
}

void Union(int i, int j) {
    int pi = Find(i);
    int pj = Find(j);
    if(pi == pj) return ;
    else f[pi] = pj;
}

bool dist(int i, int j) {
    double dd = sqrt(1.0*(a[i].x-a[j].x)*(a[i].x-a[j].x)+1.0*(a[i].y-a[j].y)*(a[i].y-a[j].y));
    if(dd <= d ) return true;
    else return false;
}

int main() {
    scanf("%d%lf", &n, &d);
        for(int i = 1; i <= n; i++) {
            scanf("%d%d", &a[i].x, &a[i].y);
            f[i] = i;
        }
        char op[2];
        int p, q, cnt = 0;
        memset(repaired, 0, sizeof(repaired));
        while(scanf("%s%d", &op, &p) != EOF) {
            if(op[0] == 'O') {
                for(int i = 0; i < cnt; i++) {      //与已修好的电脑合并
                    if(dist(repaired[i], p))
                        Union(repaired[i], p);
                }
                repaired[cnt++] = p;

            }
            else {
                scanf("%d", &q);
                if(Find(p) == Find(q)) printf("SUCCESS\n");
                else printf("FAIL\n");
            }

        }

    return 0;
}


你可能感兴趣的:(POJ2236--Wireless Network)