并查集 poj2236
网址:http://poj.org/problem?id=2236
题意:有n台坏的电脑,如果每两台电脑的距离不能超过d,那么这两台电脑有联系,用字符串O 表示标记第x台电脑维修了,用S判断从X到y是否有联系。。。
题解:用并查集记录和查找每个点的父亲节点,每次输入的同时遍历该点和其他点是否有联系(即距离小于等于的)。。。。。
![](https://i-blog.csdnimg.cn/blog_migrate/e3b1ed31c99b10c6259b3e420745f9cd.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/cb229652b0497e379bc028680819adea.gif)
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 using namespace std;
5 struct point
6 {
7 int x,y;
8 int pre;
9 bool k;
10 }p[1002];
11 void New(int n)
12 {
13 for(int i=1; i<=n; i++)
14 {
15 p[i].pre=i;
16 }
17 }
18 int find(int x)
19 {
20 if(p[x].pre!=x)
21 {
22 p[x].pre=find(p[x].pre);
23 }
24 return p[x].pre;
25 //return x == p[x].pre ? x : find(p[x].pre);
26 }
27 int dis(point p1,point p2)
28 {
29 return (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y);
30 }
31 void Union(point p1,point p2,int d)
32 {
33 int root1=find(p1.pre);
34 int root2=find(p2.pre);
35 if(root1 != root2)
36 {
37 if( dis(p1,p2) <= d * d )
38 {
39 p[root2].pre = root1;
40 }
41 }
42 }
43 int main()
44 {
45 char s;
46 int n , d;
47 scanf( "%d%d", &n ,&d);
48 New(n);
49 for(int i = 1 ; i <= n; i++)
50 {
51 scanf( "%d%d", &p[i].x , &p[i].y);
52 }
53 while(~scanf("\n%c", &s))
54 {
55 int r , a, b;
56 if(s=='O')
57 {
58 scanf("%d", &r);
59 p[r].k=1;
60 for(int i = 1; i <= n; i++)
61 if(p[i].k && i != r)
62 Union(p[i] , p[r],d);
63 }
64 else
65 {
66 scanf("%d%d", &a, &b);
67 if(find(a) == find(b))
68 printf("SUCCESS\n");
69 else
70 printf("FAIL\n");
71 }
72 }
73 }