step1:在输入每个点的坐标后,首先根据计算的通信范围建立每对计算机的连通关系。
step2:当输入的操作是维修时,就将本台计算机标记为完好,并将其所有与其可以通信的且完好的计算机进行并操作,那么可通信的计算机就在一棵树中了,具有相同的根节点。
step3:当输入的操作为查询时,若两计算机具有相同的根节点,则可以通信,否则不可以通信。
http://poj.org/problem?id=2236
1 #include<stdio.h>
2 #include<string.h>
3 #include<stdlib.h>
4 #include<math.h>
5 int map[1005][1005];
6 int mul(int x)
7 {
8 return x*x;
9 }
10 int f[1005];
11 int find(int x)
12 {
13 if(f[x]!=x)
14 f[x]=find(f[x]);
15 return f[x];
16 }
17 void make(int a,int b)
18 {
19 int f1=find(a);
20 int f2=find(b);
21 if(f2!=f1)
22 f[f2]=f1;
23 }
24 void check(int a,int b) //检查a与b是否连通,并输出
25 {
26 int f1=find(a);
27 int f2=find(b);
28 if(f1==f2)
29 {
30 printf("SUCCESS
");
31 return ;
32 }
33 printf("FAIL
");
34 }
35 int main()
36 {
37 int flag[1005],n,i,j,k;
38 double d;
39 memset(map,0,sizeof(map));
40 memset(flag,0,sizeof(flag));
41 while(scanf("%d%lf",&n,&d)!=EOF)
42 {
43 int x[1005],y[1005];
44 for(i=1;i<=n;i++)
45 scanf("%d%d",&x[i],&y[i]);
46 for(i=1;i<=n;i++)
47 f[i]=i;
48 for(i=1;i<=n;i++) //对可直接进行通信的计算机进行标记
49 for(j=i+1;j<=n;j++)
50 if(sqrt((double)(mul(x[i]-x[j])+mul(y[i]-y[j])))<=d)
51 {
52 map[i][j]=1;
53 map[j][i]=1;
54 }
55 char s[5];
56 int a,b;
57 while(scanf("%s",s)!=EOF)
58 {
59 if(strcmp(s,"O")==0)
60 {
61 scanf("%d",&a);
62 flag[a]=1;
63 for(i=1;i<=n;i++)
64 if(map[i][a]&&flag[i]) //将可直接通信的并且完好的计算机合并为一个集合
65 make(a,i);
66 }
67 else
68 {
69 scanf("%d%d",&a,&b);
70 check(a,b);
71 }
72 }
73
74 }
75 return 0;
76 }