Wireless Network POJ-2236

题目:https://vjudge.net/problem/POJ-2236

题目大意

地震了有n个电脑要修,两个电脑要连接距离不能超过d。如果AB要连接有两种情况,A直接连接B, AB不能直接连接但是A连接C,B连接C。给你两种操作,O意味着修复S意味着测试能否连接

分析

很明显是一个并查集题,模版加上一些限制就能过。

代码

#include <cstdio>
#include <iostream>
#include <string.h>
#include <cmath>
#include <cstdlib>
using namespace std;
#define NUM 1001
int pre[NUM];
int pos[NUM][NUM];
bool conn[NUM];
float dis[NUM];

int n, d;

int find_(int x){
    int t = x;
    while(t != pre[t]){
        t = pre[t];
    }

    int k = x;
    while(k != t){
        int s = pre[k];
        pre[k] = t;
        k = s;
    }

    return t;
}

bool join_(int x, int y){
    int xx = find_(x);
    int yy = find_(y);

    if(xx != yy){
        pre[yy] = xx;
        return false;
    }
    return true;
}

void op_0(int p){
    conn[p] = true;

    for(int i = 1; i <= n; i++){
        if(conn[i] && conn[p]){
                int &x1 = pos[i][0];
                int &y1 = pos[i][1];
                int &x2 = pos[p][0];
                int &y2 = pos[p][1];
                int dx = abs(x1 - x2);
                int dy = abs(y1 - y2);
                float dd;
                dd = sqrt(dx * dx + dy * dy);
                if(dd <= d){
                    join_(i, p);
                }
            }
        }

}


bool op_S(int p, int q){

    int pp = find_(p);
    int qq = find_(q);
    if(pp == qq){
        return true;
    }
    else{
        return false;
    }
}


int main(){

//  freopen("B.txt", "r", stdin);

    scanf("%d%d", &n, &d);

    for(int i = 0; i <= n; i++){
        pre[i] = i;
    }

    memset(conn, false, sizeof(conn));

    for(int i = 1; i <= n; i++){
        int a, b;
        scanf("%d%d", &a, &b);
        pos[i][0] = a;
        pos[i][1] = b;
    }

    char s;
    while(cin >> s){
        if(s == 'O'){
                int p;
                scanf("%d", &p);
                op_0(p);
        }
        else if(s == 'S'){
                int pp, q;
                scanf("%d%d", &pp, &q);
                if(op_S(pp, q)){
                    printf("SUCCESS\n");
                }
                else{
                    printf("FAIL\n");
                }       
        }       
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值