poj 2236 Wireless Network

 

提题意是n台损坏的电脑,现要将其逐台修复,且使其相互恢复通信功能。若两台电脑能相互通信,

则有两种情况,一是他们之间的距离小于d,二是他们可以借助都可到达的第三台已修复的电脑。

给出所有电脑的坐标位置,对其进行两种可能的操作,O x表示修复第x台,S x y表示判断x y之间能否通信,

若能输出SUCCESS,否则输出FALL。

思路:判断图的连通性问题,可以借助并查集。首先,电脑之间若能通信,则大前提就是两台电脑都是维修过的,

因此处理联通问题时,必须在已修好的电脑中进行。由于通信可以传递,因此只要满足能够通信的条件,则新加入

的电脑就可以借助这个小网络与其中任意一台通信,这就是使用并查集的关键条件,因此,将满足距离关系的电脑

并入一个集合中,此后每加入一台电脑都与前面加入的所有电脑做一次联通性的判断,即只要距离小于d就并入集合即可。

#include <stdio.h>
#include <math.h>

int n, rank[1005], arr[1005], repaired[1005];

struct Pos {
    int x, y;
} pos[1005];

void make()
{
    for (int i = 1; i <= n; ++i)
        rank[i] = 0, arr[i] = i;
}

int find(int x)
{
    if (x != arr[x])
        arr[x] = find(arr[x]);
    return arr[x];
}

void merge(int x, int y)
{
    x = find(arr[x]);
    y = find(arr[y]); // 多向上找一层
    if (x != y)
    {
         if (rank[x] < rank[y])
            arr[x] = y;
        else
        {
            arr[y] = x;
            if (rank[x] == rank[y])
                ++rank[x];
        }
    }
}

double distance(int a, int b) // 注意标号转换一下
{
    Pos x, y;
    x = pos[a];
    y = pos[b];
    return sqrt(1.0*(x.x-y.x)*(x.x-y.x) + 1.0*(x.y-y.y)*(x.y-y.y));
}

int main()
{
    char ch;
    int i, x, y, cnt;
    double d;
    scanf("%d%lf", &n, &d);
    for (i = 1; i <= n; ++i) // 编号1到n..
        scanf("%d%d", &pos[i].x, &pos[i].y);
    cnt = 0;
    make();
    while (scanf(" %c%d", &ch, &x) != EOF)
        if (ch == 'O')
        {
            for (i = 0; i < cnt; ++i) // 与已修好的电脑合并
                if (distance(repaired[i], x) <= d)
                    merge(repaired[i], x);
            repaired[cnt++] = x; // 加入修好的集合中,逻辑其实恰好相反,是先修再合并
        }
        else
        {
             scanf("%d", &y);
             if (find(x) == find(y)) // 判断连通性
                 printf("SUCCESS\n");
             else
                 printf("FAIL\n");
        }
    return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值