POJ2236 Wireless Network(并查集)
Wireless Network
Time Limit: 10000MS | Memory Limit: 65536K | |
---|---|---|
Total Submissions: 38703 | Accepted: 16044 |
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:
- "O p" (1 <= p <= N), which means repairing computer p.
- "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行表示1-N的计算机的位置xi,yi。接下来不超过300000行的输入。O表示计算机修复成功,S表示测试两台计算机能否通信。
思路
利用并查集进行维护。每次O之后,对于其他已经修复的计算机进行问询,如果距离在d之内。进行合并操作。每次S,判断两台计算机的父亲节点是否相同即可判断能否进行通信。
这道简单题浪费了不少时间,先是犯了从0计数<=MAXN,的RE错误,又是在find过程中返回了x。
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e3+10;
int fat[MAXN];
vector<int> v1;
vector<int>::iterator iter;
struct Node{
int x;
int y;
}po[MAXN];
int N,d;
void init(){
memset(po,0,sizeof(po));
v1.clear();
for(int i=0;i<MAXN;i++) fat[i] = i;
}
int find(int x){
if(fat[x]==x) return x;
else{
int t = fat[x];
fat[x] = find(t);
}
return fat[x];
}
void merge(int x,int y){
int fx = find(x);
int fy = find(y);
if(fx!=fy){
fat[fx] = fy;
}
return ;
}
int jud(int cur,int a){
int x1 = po[cur].x;
int x2 = po[a].x;
int y1 = po[cur].y;
int y2 = po[a].y;
if((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)<=(d*d)) return 1;
else return 0;
}
int main() {
scanf("%d %d",&N,&d);
init();
for(int i=1;i<=N;i++){
int a,b;
scanf("%d %d",&a,&b);
po[i].x = a;
po[i].y = b;
}
char str[10];
while(~scanf("%s",str)){
if(str[0]=='O'){
int a;
scanf("%d",&a);
for(iter=v1.begin();iter!=v1.end();iter++){
int cur = *iter;
if(jud(cur,a)==1&&cur!=a) merge(cur,a);
}
v1.push_back(a);
}else{
int a,b;
scanf("%d %d",&a,&b);
if(find(a)==find(b)) printf("SUCCESS\n");
else printf("FAIL\n");
}
}
return 0;
}