题目:poj 2236 Wireless Network(并查集)
题目大意:地震后,学校的电脑全部都坏了,然后需要修理,修理的时候还需要测试一下两台电脑之间是否可以联通,这需要这两台电脑都是好的,而且规定在距离d 之间的电脑才可以直接联通,否则就需要借助其它的点脑使这两台电脑联通也行。
解题思路:将每次修理的电脑做记录,然后每次修好电脑就和其他的修好的距离合适的电脑进行连接,并入集合中。这里就需要将每个电脑与它距离小于等于d的电脑存到一个数组中。这样里面的两台电脑要不就是直接连接要不就是借助另一台电脑进行连接。最后能不能链接就看在不在同一个集合中就行了。
代码:
#include <stdio.h>
#include <string.h>
#include <math.h>
const int N = 1005;
struct MAP {
double xi, yi;
}s[N];
int f[N], fix[N], g[N][N], c[N], n;
double d;
double dis (double i, double j) {
return sqrt(i * i + j * j);
}
int getfather ( int x) {
return f[x] = (x == f[x]) ? x : getfather (f[x]);
}
void init () {
memset (fix, 0, sizeof (fix));
memset (c, 0, sizeof (c));
for (int i = 0; i <= n; i++)
f[i] = i;
for (int i = 1; i <= n; i++) {
scanf ("%lf%lf", &s[i].xi, &s[i].yi);
for (int j = 1; j < i; j++) {
double di = dis (s[i].xi - s[j].xi, s[i].yi - s[j].yi);
if (d - di >= -1e-9) {
g[i][c[i]++] = j;
g[j][c[j]++] = i;
}
}
}
}
int main () {
scanf ("%d%lf", &n, &d);
init();
char str[10];
int x, y;
while (scanf ("%s", str) == 1) {
if (str[0] == 'O') {
scanf ("%d", &x);
fix[x] = 1;
int p = getfather(x);
for (int i = 0; i < c[x]; i++) {
if (fix[g[x][i]] == 0)
continue;
int q = getfather(g[x][i]);
if (p != q)
f[q] = p;
}
}else {
scanf ("%d%d", &x, &y);
int p = getfather(x);
int q = getfather(y);
if (p == q)
printf ("SUCCESS\n");
else
printf ("FAIL\n");
}
}
return 0;
}