问题 B: 并查集_无线网络
时间限制: 1 Sec 内存限制: 128 MB提交: 3 解决: 2
[ 提交][ 状态][ 讨论版]
题目描述
一场地震在东南亚发生了。不幸的是ACM组织通过电脑建立的无线网络遭到了毁灭性的影响—--网络中所有的电脑都损坏了。在陆续的维修电脑之后,无线网络有逐渐开始再一次运作了。由于硬件的制约,每两台电脑只能保持不超过d米的距离,才可以直接进行通讯。但是每台电脑又可以作为其它两台电脑通讯的中介点,也就是说假设A电脑与B电脑不在能直接通讯的的范围内,但是它们可以通过同时能与A和B电脑通讯的C电脑建立间接通讯关系。
在维修的过程中,维修者可以进行两种操作:维修一台电脑或者检测两台电脑之间是否能够通讯。你的任务就是解答每一次的检测操作。
输入
第一行包含两个整数N和d (1 <= N <= 1001, 0 <= d <= 20000).N表示电脑的数量,电脑编号从1开始到N,d为两台能直接通讯的电脑所需保持的距离的最大值。在接下来的N行里,每行包含两个整数xi, yi (0 <= xi, yi <= 10000),表示N台电脑的坐标。接下来的一系列的输入都表示维修者的操作,每种操作都是以下两种中的一种:
1. "O p" (1 <= p <= N),表示维修第p台电脑。
2. "S p q" (1 <= p, q <= N), 表示检测p与q电脑是否能够通讯。
输入不会超过300000 行。
输出
对于每组检测操作,若两台电脑能进行通讯就输出"SUCCESS",否则输出"FAIL"。
样例输入
4 1
0 1
0 2
0 3
0 4
O 1
O 2
O 4
S 1 4
O 3
S 1 4
样例输出
FAIL
SUCCESS
提示
没有神马好看的 本题就是一个普通的并查集
#include<stdio.h> #include<math.h> struct haha { int x; int y; int flag; }a[2000]; int parent[2000]; int find(int x) { return x==parent[x]?x:find(parent[x]); } int main() { int i,j,n,x,y,start,end,r1,r2,pos; double k,d; char s[2]; scanf("%d %lf",&n,&d); for(i=1;i<=n;i++) { scanf("%d %d",&x,&y); a[i].x=x; a[i].y=y; a[i].flag=0; parent[i]=i; } while(scanf("%s",s)!=EOF) { if(s[0]=='O') { scanf("%d",&pos); a[pos].flag=1; for(i=1;i<=n;i++) if(a[i].flag) { k=sqrt((a[pos].x-a[i].x)*(a[pos].x-a[i].x)+(a[pos].y-a[i].y)*(a[pos].y-a[i].y)); if(k<=d) { r1=find(pos); r2=find(i); if(r1!=r2) parent[r1]=r2; } } } if(s[0]=='S') { scanf("%d %d",&start,&end); // if(!a[start].flag||!a[end].flag) {printf("FAIL\n"); continue;} r1=find(start); r2=find(end); if(r1==r2){printf("SUCCESS\n");} // k=sqrt((a[start].x-a[end].x)*(a[start].x-a[end].x)+(a[start].y-a[end].y)*(a[start].y-a[end].y)); // if(k<=d) {printf("SUCCESS\n"); parent[r1]=r2;continue;} else printf("FAIL\n"); } } }