poj2236 并查集板子题

题目大意:

  给你N台电脑和一个距离D,然后给你N台电脑的坐标xi,yi,0<=xi,yi<=10000,d<=20000,给你最多3e5次查询,每次查询中,(O x)表示修复了x号电脑,(S x y)表示询问x和y是否可以通信,返回查询结果(如果两台电脑距离在d之内,那么两台电脑可以相连)

题解:

  一共3e5次查询,但是最多有1000个点,所以最多修复1000台电脑,枚举所有电脑,找到他周围可以连接的电脑,进行合并(一开始想的是,如果修复3e5次,直接时间爆炸,不过后来发现最多修1e3次,傻了。。。)给了10s,直接水过

  不知道为啥我开始想的时候是在连接的时候就进行合并,然后修复的时候再找边,一定是失了智。。。

贴上代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #define mem(a,b) memeset(a,b,sizeof(b))
 5 using namespace std;
 6 const int maxn=1e3+10;
 7 int parent[maxn],vis[maxn],rank[maxn];
 8 int d,n;
 9 struct node
10 {
11     int x,y;
12     node(){}
13     node(int a,int b):x(a),y(b){}
14 }pc[maxn];
15 double len(node a,node b)
16 {
17     int x=a.x-b.x;
18     int y=a.y-b.y;
19     return sqrt(x*x+y*y);
20 }
21 int find(int x)
22 {
23     int k, j, r;
24     r = x;
25     while(r != parent[r])
26         r = parent[r];
27     k = x;
28     while(k != r)
29     {
30         j = parent[k];
31         parent[k] = r;
32         k = j;
33     }
34     return r;
35 }
36 void merg(int x,int y)
37 {
38     int fx=find(x);
39     int fy=find(y);
40     if(rank[fx]<=rank[fy])
41     {
42         parent[fy]=fx;
43         rank[fx]++;
44     }
45     else
46     {
47         parent[fx]=fy;
48         rank[fy]++;
49     }
50 }
51 void ini()
52 {
53     for(int i=1;i<=maxn;i++) parent[i]=i;
54 }
55 int main()
56 {
57     ini();
58     scanf("%d%d",&n,&d);
59     for(int i=1;i<=n;i++)
60     {
61         scanf("%d%d",&pc[i].x,&pc[i].y);
62     }
63     char s;
64     while(cin>>s)
65     {
66         int a,b;
67         if(s=='O')
68         {
69             scanf("%d",&a);
70             if(vis[a]) continue;
71             vis[a]=1;
72             for(int i=1;i<=n;i++)
73             {
74                 if(a==i) continue;
75                 if(len(pc[a],pc[i])>d) continue;
76                 if(!vis[i]) continue;
77                 else merg(a,i);
78             }
79             /*for(int i=1;i<=n;i++)
80             {
81                 printf("%d ",parent[i]);
82             }puts("\n");*/
83         }
84         else
85         {
86             scanf("%d%d",&a,&b);
87             int fa=find(a);
88             int fb=find(b);
89             if(fa==fb) printf("SUCCESS\n");
90             else printf("FAIL\n");
91         }
92     }
93     return 0;
94 }
View Code

 

posted @ 2018-12-06 19:40  codeoos  阅读(126)  评论(0编辑  收藏  举报