POJ_2236_(并查集小变形)
- 2层循环找出每个点 周围与其距离
<=d
的点,vector<int> p[maxn]
记录, O
的意思是修复O
附近的点,但是必须是已经出现过的需要被修复的点,(从样例我们可以看出来),用vis[]
标记一下需要修复的点,- 其他的就是并查集了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
const int maxn = 1e3+10;
int n,d;
struct node {
int x,y;
} e[maxn];
vector<int> p[maxn];
int pre[maxn];
bool vis[maxn];
void process() {
for (int i=1; i<=n; i++) {
for (int j=1; j<=n; j++) {
if (i == j) continue;
double dx = e[i].x - e[j].x;
double dy = e[i].y - e[j].y;
if (sqrt(dx*dx+dy*dy) <= d) {
p[i].push_back(j);
}
}
}
}
int find(int x) {
if (x == pre[x]) return x;
return pre[x] = find(pre[x]);
}
void init() {
for (int i=1; i<=n; i++) pre[i] = i;
}
void merge(int x) { //修复x周围的点
int rx = find(x);
for (int i=0; i<p[x].size(); i++) {
int ra = find(p[x][i]);
if (rx == ra) continue;
if(vis[p[x][i]]) pre[ra] = rx;
}
}
bool query(int a,int b) {
return find(a)==find(b);
}
int main() {
// freopen("a.txt","r",stdin);
scanf("%d%d",&n,&d);
for (int i=1; i<=n; i++) {
scanf("%d%d",&e[i].x,&e[i].y);
}
init();
process();
/*for (int i=1; i<=n; i++)
for (int j=0; j<p[i].size();j++)
printf("cur=%d to=%d\n",i,p[i][j]);
*/
char ch;
while (scanf("\n%c",&ch) != EOF) {
if (ch == 'O') {
int x;
vis[x] = 1;
scanf("%d",&x);
merge(x);
/*printf("merge:%d \n",x);
for (int i=1; i<=n; i++)
printf("%d ",pre[i]);*/
}
else {
int a,b;
scanf("%d%d",&a,&b);
if (query(a,b))
printf("SUCCESS\n");
else
printf("FAIL\n");
}
}
return 0;
}
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!