poj2236(并查集)
题目链接: http://poj.org/problem?id=2236
题意: 有n台计算机, 已知每台计算机的坐标, 初始时所有计算机都是坏的, 然后修复其中一些计算机, 已修复的计算机距离不超过distance的可以联网(若a, b之间可以联网, b, c之间可以联网, 则a, c之间可以联网),询问x, y之间可否联网;
第一行输入n, distance, 表示有n台计算机, 联网的两台计算机距离不能超过distance;
接下来n分别表示n台计算机的坐标;
再接下来到输入结束, 输入格式为: O, x 的表示修复第x台计算机, 输入格式为S, x, y 的表示询问x, y之间能否联网, 若能输出 SUCCESS, 不能则输出 FAIL;
思路: 直接并查集就好啦, 将能联网的计算机合并就OK啦...
代码:
1 #include <iostream>
2 #include <stdio.h>
3 #include <algorithm>
4 #include <math.h>
5 #define D(x1, y1, x2, y2) sqrt(pow(x2-x1, 2)+pow(y2-y1, 2))
6 #define MAXN 1010
7 using namespace std;
8
9 int pre[MAXN];
10 struct Node{
11 int x, y, flag;
12 }gg[MAXN];
13
14 int find(int x){ //***递归路径压缩
15 return x==pre[x]?pre[x]:pre[x]=find(pre[x]);
16 }
17
18 void jion(int x, int y){//***合并
19 int fx=find(x);
20 int fy=find(y);
21 if(fx!=fy){
22 pre[fy]=fx;
23 }
24 }
25
26 int main(void){
27 int n, distance;
28 scanf("%d%d", &n, &distance);
29 for(int i=1; i<=n; i++){
30 int x, y;
31 scanf("%d%d", &x, &y);
32 gg[i].x=x;
33 gg[i].y=y;
34 gg[i].flag=0;
35 }
36 for(int i=1; i<=n; i++){
37 pre[i]=i;
38 }
39 char ch[2];
40 int x, y;
41 while(~scanf("%s", ch)){
42 if(ch[0]=='O'){
43 scanf("%d", &x);
44 gg[x].flag=1;
45 for(int i=1; i<=n; i++){
46 if(i!=x&&gg[i].flag){ //**如果i不是x且i已修复
47 if(D(gg[x].x, gg[x].y, gg[i].x, gg[i].y)<=distance&&find(x)!=find(i)){ //**x, i属于不同集合,并且他们的距离不大于distance
48 jion(x, i);
49 }
50 }
51 }
52 }else{
53 scanf("%d%d", &x, &y);
54 if(find(x)==find(y)){
55 printf("SUCCESS\n");
56 }else{
57 printf("FAIL\n");
58 }
59 }
60 }
61 return 0;
62 }
我就是我,颜色不一样的烟火 --- geloutingyu