Wireless Network

Time Limit: 10000MS Memory Limit: 65536K
Total Submissions: 46995 Accepted: 19311

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,只要在这个距离,电脑之间可以相互连接。一开始电脑都是坏的,下面有两种操作:O X修复X号电脑,S X Y,查询x和y电脑是否可以通行,两台电脑之间可以通信的定义:X与Y之间相连接,X与Z通信,Z与Y通行,则X与Y通行。
思路:
先存每台电脑的坐标,等下用来计算距离的,然后当输出O X,用存完全图的方法,把已经修复的电脑相互连接,在d这个范围内,用并查集把已经修复的电并且在d这个距离内的电脑并起来,查询的时候如果这两台电脑同一棵树上则可以通信,否则步行。
最近在做并查集专题个人感觉并查集挺难的,他可以与图论相互结合,然后还有并查集查询合并操作如果有权,这个公式是比较难推的,还有就是很难想到怎么用并查集去做,感觉比图论还难一点。。。。
代码:

#include<iostream>
#include<cmath> 
#include<cstdio>
using namespace std;

const int maxn=1e3+10;
int r[maxn],f[maxn];
struct node{
	int x,y;
}a[maxn];
int n;
double d;
int find(int x){
	if(x!=f[x]){
		f[x]=find(f[x]);
	}
	return f[x];
}
void ufs(int a,int b){
	int fa=find(a);
	int fb=find(b);
	if(fa!=fb)
		f[fa]=fb;
}
double dis(int a,int b){
	return (double)sqrt((double)a*a+b*b);
}
int main(){
	scanf("%d%lf",&n,&d);
	for(int i=1;i<=n;i++){
		f[i]=i;r[i]=0;
	}
	for(int i=1;i<=n;i++){
		scanf("%d%d",&a[i].x,&a[i].y);
	}
	/*for(int i=1;i<=n;i++){//这样子合并存在一个问题,就是在没有考虑机器修复情况,只考虑了距离来合并 for(int j=i+1;j<=n;j++){//查询的时候O(n)遍历查询,但是电脑不一定是连续的 if(i!=j){ if(dis(a[j].x-a[i].x,a[j].y-a[i].y)<=d){ ufs(i,j); } } } }*/
	int j=0;
	char ch;int from,to;
	while(cin>>ch){
		if(ch=='S'){
			scanf("%d%d",&from,&to);
			if(find(from)==find(to)){
				cout<<"SUCCESS"<<endl;
			}else{
				cout<<"FAIL"<<endl;
			}
		}else{
			scanf("%d",&r[j]);//存已经修复了的电脑编号 
			for(int i=0;i<j;i++){//完全图存边 
				if(dis(a[r[i]].x-a[r[j]].x,a[r[i]].y-a[r[j]].y)<=d){
					ufs(r[i],r[j]);
				}
			}
			j++;
		}
	}
}