【并查集】POJ2236-Wireless Network

【题目大意】

已知每一台电脑只能与它距离为d的电脑相连通,但是两台电脑间可以以第三台作为媒介连接。现在电脑全被损坏。每次可以进行两个操作中的一个,或是修好一台电脑,或是查询两台电脑是否连通。

【思路】

显然是并查集。每次修好一台新电脑,就与之前修好的每一台电脑进行判断,距离在d以内就合并。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 const int MAXN=1001+50;
 6 int n,d;
 7 int x[MAXN],y[MAXN],rep[MAXN];
 8 int h[MAXN],pa[MAXN];
 9 
10 int ind(int a,int b)
11 {
12     return ((x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b])<=d*d);
13 }
14 
15 void newset()
16 {
17     for (int i=0;i<n;i++)
18     {
19         h[i]=0;
20         pa[i]=i;
21     }
22 }
23 
24 int find(int x)
25 {
26     int r=x;
27     while (pa[r]!=r) r=pa[r];
28     int p=x;
29     while (pa[p]!=r)
30     {
31         int temp=pa[p];
32         pa[p]=r;
33         p=temp;
34     }
35     return r;
36 }
37 
38 void unionset(int fa,int fb)
39 {
40     if (h[fa]>=h[fb])
41     {
42         pa[fb]=fa;
43         if (h[fa]==h[fb]) h[fa]++;
44     }
45     else
46         pa[fa]=fb;
47 }
48 
49 int main()
50 {
51     scanf("%d%d",&n,&d);
52     for (int i=0;i<n;i++)
53     {
54         scanf("%d%d",&x[i],&y[i]);
55     }
56     
57     char c;
58     int repd=0;//ÒѾ­Ð޺õĵçÄÔÊýÁ¿ 
59     newset();
60     
61     getchar();
62     while (scanf("%c",&c)!=EOF)
63     {
64         if (c=='S')
65         {
66             int a,b;
67             scanf("%d%d",&a,&b);
68             a--;
69             b--;
70             if (find(a)==find(b)) cout<<"SUCCESS"<<endl;else cout<<"FAIL"<<endl; 
71         }
72         
73         else
74         {
75             int a;
76             scanf("%d",&a);
77             a--;
78             for (int i=0;i<repd;i++)
79             {
80                 if (ind(a,rep[i]))
81                 {
82                     int fa=find(a),fb=find(rep[i]);
83                     unionset(fa,fb); 
84                 }
85             }
86             rep[repd]=a;
87             repd++;
88         }
89         getchar();
90     }
91     return 0;
92 }
原文地址:https://www.cnblogs.com/iiyiyi/p/4739431.html