poj 2236 Wireless Network(并查集)

39 篇文章 0 订阅
7 篇文章 0 订阅
Wireless Network
点击打开题目链接
Time Limit: 10000MS Memory Limit: 65536K
Total Submissions: 15990 Accepted: 6750

Description

An earthquake takes place in Southeast Asia. The ACM (Asia Cooperated Medical team) have set up a wireless network with the lap computers, but an unexpected aftershock attacked, all computers in the network were all broken. The computers are repaired one by one, and the network gradually began to work again. Because of the hardware restricts, each computer can only directly communicate with the computers that are not farther than d meters from it. But every computer can be regarded as the intermediary of the communication between two other computers, that is to say computer A and computer B can communicate if computer A and computer B can communicate directly or there is a computer C that can communicate with both A and B.

In the process of repairing the network, workers can take two kinds of operations at every moment, repairing a computer, or testing if two computers can communicate. Your job is to answer all the testing operations.

Input

The first line contains two integers N and d (1 <= N <= 1001, 0 <= d <= 20000). Here N is the number of computers, which are numbered from 1 to N, and D is the maximum distance two computers can communicate directly. In the next N lines, each contains two integers xi, yi (0 <= xi, yi <= 10000), which is the coordinate of N computers. From the (N+1)-th line to the end of input, there are operations, which are carried out one by one. Each line contains an operation in one of following two formats:
1. "O p" (1 <= p <= N), which means repairing computer p.
2. "S p q" (1 <= p, q <= N), which means testing whether computer p and q can communicate.

The input will not exceed 300000 lines.

Output

For each Testing operation, print "SUCCESS" if the two computers can communicate, or "FAIL" if not.

Sample Input

4 1
0 1
0 2
0 3
0 4
O 1
O 2
O 4
S 1 4
O 3
S 1 4

Sample Output

FAIL
SUCCESS

Source

POJ Monthly,HQM
题意:
第一行输入两个数n和d,其中n代表电脑的个数,d代表电脑能通信的最大距离;
接下来n行,每行有两个数,代表电脑的坐标(x,y)
从第n+1行开始,每行开始先输入一个操作符op:
如果op==‘O’,则接着输入一个数x,代表编号为x的电脑已经修好;
如果op==‘S’,则接着输入两个数,x,y,检测x,y是否可以通信,如果可以则输出SUCCESS,否则输出FAIL;
解题思路:
定义一个数的节点代表集合中的元素:
struct uftree
{
    int x,y;//这台电脑的坐标
    int parent;//这台电脑的父节点
    int work;//是否能工作
    int distance(const uftree &p2)//求两个电脑之间的距离
    {
        return (this->x-p2.x)*(this->x-p2.x)+(this->y-p2.y)*(this->y-p2.y);
    }
} set[MAX];
对于op==‘O’操作:将x其置为能工作,即令其的work=1,然后遍历n,找到所有能与x通信的电脑,并使其与x所在的集合合并
对于op==‘S’操作:只要查询x,y是否在同一个集合即可,如果在同一个人集合则输出SUCCESS,否则输出:FAIL
代码:
#include<math.h>
#include<stdio.h>
#include<string.h>
#define MAX 10010
struct uftree
{
    int x,y;
    int parent;
    int work;
    int distance(const uftree &p2)
    {
        return (this->x-p2.x)*(this->x-p2.x)+(this->y-p2.y)*(this->y-p2.y);
    }
} set[MAX];
void make_set(int n)//初始化
{
    int i;
    for(i=0; i<n; i++)
    {
        set[i].work=0;
        set[i].x=0;
        set[i].y=0;
        set[i].parent=i;
    }
}
int set_find(int x)
{
    return set[x].parent==x?x:set[x].parent=set_find(set[x].parent);//查找
}
void set_join(int x,int y)//合并
{
    int px=set_find(x);
    int py=set_find(y);
    if(px!=py)
        set[px].parent=py;
}
void Operator(int x,int n,int d)
{
    int i;
    for(i=0; i<=n; i++)
    {
        if(set[i].work&&(set[i].distance(set[x])<=d*d))//合并符合条件能通信的电脑
            set_join(i,x);
    }
}
void test(int x,int y)
{
    printf("%s\n",set_find(x)==set_find(y)?"SUCCESS":"FAIL");//查询是否在同一个集合中根据查询结果输出
}
int main()
{
    int n,d,i,a,b;
    char op;
    while(~scanf("%d%d",&n,&d))
    {
        make_set(n);
        for(i=1; i<=n; i++)
            scanf("%d%d",&set[i].x,&set[i].y);
        while(~scanf("%c\n",&op))
        {
            if((op=='O'))
            {
                scanf("%d",&a);
                set[a].work=1;//将work置为1
                Operator(a,n,d);
            }
            else if(op=='S')
            {
                scanf("%d%d",&a,&b);
                test(a,b);
            }
        }
    }
    return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值