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
");
56             }else{
57                 printf("FAIL
");
58             }
59         }
60     }
61     return 0;
62 }
原文地址:https://www.cnblogs.com/geloutingyu/p/6116733.html