无线网络 POJ - 2236
东南亚发生地震。ACM(亚洲合作医疗队)与膝上电脑建立了无线网络,但意外的余震袭击了网络中的所有电脑。电脑被一台一台修好,网络也逐渐恢复了工作。由于硬件限制,每台计算机只能直接与距离它不超过d米的计算机通信。但是每台计算机都可以看作是其他两台计算机之间通信的中介,也就是说,如果计算机 A 和计算机 B 可以直接通信,或者有一台计算机 C 可以同时与 A 和计算机通信,那么计算机 A 和计算机 B 就可以通信。 B.
在修复网络的过程中,工人每时每刻都可以进行两种操作,修复一台计算机,或者测试两台计算机是否可以通信。你的工作是回答所有的测试操作。
输入
第一行包含两个整数 N 和 d(1 <= N <= 1001, 0 <= d <= 20000)。这里 N 是计算机的数量,从 1 到 N 编号,D 是两台计算机可以直接通信的最大距离。在接下来的 N 行中,每行包含两个整数 xi, yi (0 <= xi, yi <= 10000),这是 N 台计算机的坐标。从第(N+1)行到输入结束,有操作,一一进行。每行包含以下两种格式之一的操作:
- “O p” (1 <= p <= N),表示修复计算机 p。
- “S p q” (1 <= p, q <= N),表示测试计算机p和q是否可以通信。
输入不会超过300000行。
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
思路:遇见有x,y坐标的先用结构保存起来,然后第几个结构就是编号几的计算机。已经修复的电脑也要用一个结构来存着。
#include<stdio.h>
#include<string.h>
#include<queue>
#include <iostream>
#include <cmath>
using namespace std;
int n;
const int N=1101;
int num[N];
struct node{
int x;
int y;
int id;
}computer[N],repair[N];
double suan(node a,node b)
{
return sqrt((double)(a.x-b.x)*(double)(a.x-b.x)+(double)(a.y-b.y)*(double)(a.y-b.y));
}
int Find(int x)
{
return (x==num[x]?x:num[x]=Find(num[x]));
}
void uino(int x,int y)
{
x=Find(x);
y=Find(y);
if(x!=y){
num[x]=y;
}
}
int main()
{
ios::sync_with_stdio(false);
int i,p,q,d,cnt;
cin>>n>>d;
for(i=1;i<=N;i++){
num[i]=i;
}
for(i=1;i<=n;i++){
cin>>computer[i].x>>computer[i].y;//用一个结构表示一个点代表一个计算机
}
char ch;
cnt=1;
while(cin>>ch){
if(ch=='O'){
cin>>p;
repair[cnt].x=computer[p].x;//已经修复的电脑
repair[cnt].y=computer[p].y;
repair[cnt].id=p;
for(i=1;i<cnt;i++){//枚举现修复的与之前已经修复的电脑的距离
if(suan(repair[i],computer[p])<=d){//可以链接则uino
uino(repair[i].id,p);
}
}
cnt++;
}
else {
cin>>p>>q;
if(Find(p)==Find(q)){//看看是否很够接通
cout<<"SUCCESS\n";
}
else cout<<"FAIL\n";
}
}
}