http://acm.pku.edu.cn/JudgeOnline/problem?id=2236
#include<stdio.h>
#include<math.h>
#include<iostream>
using namespace std;
const int MAX = 1100;
int join[MAX];
double dis[MAX][MAX];
double zuob[MAX][2];

class UnionFindSet
{
public:
 int parent[MAX];
 UnionFindSet();
    int Union(int x, int y);
 int Find(int i);
};
UnionFindSet::UnionFindSet()
{
 memset(parent,-1,sizeof(parent));
}
int UnionFindSet::Union(int x, int y)
{
 x = Find(x);
 y = Find(y);
 // 找出的根节点x,parent[x]中保存的是根为x的元素的个数的相反数;
 int temp = parent[x] + parent[y];
 if(parent[x] >= parent[y])
 {
  parent[y] = x;
  parent[x] = temp;
 }
 else{
  parent[x] = y;
  parent[y] = temp;
 }
 return 0;
}
int UnionFindSet:: Find(int i)
{
 if(parent[i] < 0)
  return i;
 else{
  parent[i] = Find(parent[i]);//压缩路径;
 }
}
int main()
{
 UnionFindSet test;
 int top;
 int n, m1,m2;
 int i,j;
 double d;
 char p;
 scanf("%d%lf",&n,&d);
 for(i=1;i<=n;i++){
  scanf("%lf%lf",&zuob[i][0],&zuob[i][1]);
 }
 for(i=1;i<=n;i++)
  for(j=i+1;j<=n;j++)
   dis[j][i]=dis[i][j]=sqrt((zuob[i][0]-zuob[j][0])*(zuob[i][0]-zuob[j][0])
               +(zuob[i][1] - zuob[j][1])*(zuob[i][1]-zuob[j][1]));
 top=0;
 while(scanf("\n%c",&p)!=EOF){
  if(p=='O'){
   scanf("%d",&m1);
   join[top]=m1;
   for(i=0;i<top;i++){
    if(dis[join[i]][m1]<=d){
     //判断两个数是否已经为同一集合;
     //把if删掉后就re了.为什么会这样呢?
     if(test.Find(join[i])!=test.Find(m1))
        test.Union(join[i],m1);
    }
   }
   top++;
  }
  else{
   scanf("%d%d",&m1,&m2);
   if(test.Find(m1)==test.Find(m2))
      printf("SUCCESS\n");
   else printf("FAIL\n");
  }
 }
 return 0;
}