poj 2236 Wireless Network

题目链接:http://poj.org/problem?id=2236

题目大意:
有n台损坏的电脑,现要将其逐台修复,且使其相互恢复通信功能。若两台电脑能相互通信,则有两种情况,一是他们之间的距离小于d,二是他们可以借助都可到达的第三台已修复的电脑。给出所有电脑的坐标位置,对其进行两种可能的操作,O x表示修复第x台,S x y表示判断x y之间能否通信,若能输出SUCCESS,否则输出FALL。

解题思路:判断图的连通性问题(并查集的简单应用)
首先,电脑之间若能通信,则大前提就是两台电脑都是维修过的,因此处理联通问题时,必须在已修好的电脑中进行。
由于通信可以传递,因此只要满足能够通信的条件,则新加入的电脑就可以借助这个小网络与其中任意一台通信,这就是使用并查集的关键条件
将满足距离关系的电脑并入一个集合中,此后每加入一台电脑都与前面加入的所有电脑做一次联通性的判断,即只要距离小于等于d就并入集合

代码如下:
Time:1391ms Memory:0.2MB Length: 1188

#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 1110;
bool vis[maxn];

struct node
{
    int head;
    int x, y;
}c[maxn]; 

int n, d;
void init() //把每一个元素初始化为一个集合
{
    for (int i = 1; i <= n; i++)
        c[i].head = i;  //初始化后每一个元素的父亲节点是它本身,每一个元素的祖先节点也是它本身
}

int find(int x) //查找一个元素所在的集合
{
    return c[x].head == x ? x : find(c[x].head);
}

void Union(node c1, node c2) //合并c1,c2所在的两个集合
{
    int a = find(c1.head);
    int b = find(c2.head);
    if(a!=b)
        if((c1.x - c2.x)*(c1.x - c2.x) + (c1.y - c2.y)*(c1.y - c2.y)<=d*d)
            c[b].head = a;
}

int main()
{
    scanf("%d %d", &n, &d);
    init();
    memset(vis, false, sizeof(vis));
    for (int i = 1; i <= n; i++)
        scanf("%d %d", &c[i].x, &c[i].y);
    char str[maxn];
    while (~scanf("%s", str))
    {
        if (str[0] == 'O')
        {
            int x;
            scanf("%d", &x);
            vis[x] = true;
            for (int i = 1; i <= n; i++)
                if (i != x&&vis[i])
                        Union(c[i], c[x]);
        }
        else {
            int x, y;
            scanf("%d %d", &x, &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、付费专栏及课程。

余额充值