A - Wireless Network
Time Limit:10000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u
Submit
Status
Practice
POJ 2236
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
题意:首行给出N和D,代表有N台电脑,每台电脑最大通信距离是D。接着N行,第i行两个数字代表第i台电脑的坐标。接着后面有很多行,每行第一个字符是O,代表修复O后面编号的电脑,字符是S,代表询问后面两个编号的电脑是否能通信,对于每次询问对应输出即可。
思路:并查集的水题。对于每次修复,都遍历所有已经修复过的电脑,如果他们的距离小于等于D,那么就合并到同一集合。对于每次询问,直接判断他们是不是同一个爹即可。
代码
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<string.h>
using namespace std;
const int maxn=1005;
int Father[maxn];//并查集数组
int x[maxn];
int y[maxn];//记录坐标
int num[maxn];//记录已经修好的电脑的编号
int len_num;//记录已经修好的电脑的数量
int N;//电脑数量
int D;//最大通信距离
void init()//初始化并查集数组
{
for(int i=1; i<=N; i++)
Father[i]=i;
}
int Query(int x)
{
if(x!=Father[x])
Father[x]=Query(Father[x]);//路径压缩
return Father[x];
}
bool Judge(int i,int j)//判断x和y电脑的距离是否小于D
{
if((double)sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]))<=(double)D*1.0)
return 1;
return 0;
}
void Merge(int x,int y)//合并x和y电脑
{
if(Judge(x,y))//x到y距离小于等于D
{
int flag_x=Query(x);
int flag_y=Query(y);
if(flag_x!=flag_y)//不在同一集合,且距离小于等于D
Father[flag_x]=flag_y;
}
}
int main()
{
scanf("%d%d",&N,&D);
for(int i=1; i<=N; i++)
scanf("%d%d",&x[i],&y[i]);
init();
len_num=0;
char str;
while(scanf("\n%s",&str)!=EOF)
{
if(str=='O')
{
scanf("%d",&num[len_num]);
for(int i=len_num-1; i>=0; i--)
Merge(num[len_num],num[i]);
len_num++;
// for(int i=0;i<len_num;i++)//打印数据
// printf("%d ",num[i]);
// printf("\n");
// for(int i=1; i<=N; i++)
// printf("%d ",Father[i]);
// printf("\n");
}
else if(str=='S')
{
int x,y;
scanf("%d%d",&x,&y);
Query(x)==Query(y)?printf("SUCCESS\n"):printf("FAIL\n");//查询两台电脑是不是同一个爹
}
}
return 0;
}