这题,额,思路很好理解,说难其实也不难,代码也很好实现,就是慢了一点,不知道大牛是怎么过的,十分的好奇ing
//题意:题目给出 n 台电脑,距离 d,和各台电脑的坐标(x,y)。电脑要通信要满足两个条件:
// 1 电脑被修好,2 电脑之间的距离不超过距离 d 。输入 O p 时代表电脑 p 被修好,输入 S p q 时
//代表测试电脑 p 与 q 之间是否可以通信。
//思路:用到并查集。如果修好的电脑和已经被修好的电脑之间的距离小于 d ,则合并。
//最后判断两台电脑是否可以通信就通过判断电脑是否被修好,根结点是否相等。
#include<stdio.h> #include<math.h> #define MAXN 1010 int f[MAXN],k[MAXN],n,d; //f[]用来存在父节点,k[]用来表示该节点是否已经被修好 struct node { int x,y; }cor[MAXN]; int find(int x) { if(x!=f[x]) f[x]=find(f[x]); return f[x]; } void Union(int x,int y) { int a=find(x); int b=find(y); if(a!=b) f[a]=b; }//合并 int test(int a,int b)//判定距离是否小于d { int l; l=((cor[a].x-cor[b].x)*(cor[a].x-cor[b].x)+(cor[a].y-cor[b].y)*(cor[a].y-cor[b].y)); if(l<=d) return 1; else return 0; } int main() { int i,o=0,a,b; char ch[2]; scanf("%d %d",&n,&d); d=d*d; for(i=1;i<=n;i++) scanf("%d %d",&cor[i].x,&cor[i].y); for(i=1;i<=n;i++)//初始化 { f[i]=i; k[i]=0; } while(scanf("%s",ch)!=EOF) { if(ch[0]=='O') { o++; scanf("%d",&a); if(o==1) { k[a]=1;continue; }//这里第一个修理的就不用合并了吧,避免了一个循环,不过也快不了多少本身 else { k[a]=1; for(i=1;i<=n;i++) { if(k[i]&&test(i,a))//该点已修好,且距离符合要求,则合并 Union(i,a); } } } else { scanf("%d %d",&a,&b); if(test(a,b)|| (find(a)==find(b)))//直接连接符合要求,或者已经合并到一起 printf("SUCCESS\n"); else printf("FAIL\n"); } } return 0; }