并查集的基本应用
题目:输入电脑个数n,(电脑标号为1到n)相邻电脑交流的最大距离d。输入n台电脑的坐标。
起初n台电脑均被破坏。两台电脑之间可通过第三台电脑相互交流。
下边有两种输入:
O i。修复第i台电脑
S a b 判断电脑a和b是否能交流,若能输出SUCCESS,否则输出FAIL。
起初n台电脑均被破坏。两台电脑之间可通过第三台电脑相互交流。
下边有两种输入:
O i。修复第i台电脑
S a b 判断电脑a和b是否能交流,若能输出SUCCESS,否则输出FAIL。
思路:
用并查集处理。
输入遇到O:标记当前电脑已修复,找出已修复的其他所有电脑看是否能合并(距离是否满足条件)
遇到S:如果输入的两台电脑在同一连通分量里边,说明可以交流,否则不行。
#include <cstdio>
#include <cstring>
#define N 1005
using namespace std;
typedef struct note {
int x, y;
}node;
node pos[N];
int f[N],sign[N];
int n, d;
void init()
{
for (int i = 1; i <= n; i++)
{
f[i] = i;
sign[i] = 0;
}
}
int find(int x)
{
return x == f[x] ? x : f[x] = find(f[x]);
}
void merge(int x, int y)
{
int t1 = find(x), t2 = find(y);
if (t1 != t2) f[t2] = t1;
}
int same(int x, int y)
{
return find(x) == find(y);
}
int judge(int a, int b)
{
return (pos[a].x - pos[b].x)*(pos[a].x - pos[b].x) + (pos[a].y - pos[b].y)*(pos[a].y - pos[b].y) <= d*d ? 1 : 0;
}
int main()
{
scanf("%d%d", &n, &d);
for (int i = 1; i <= n; i++)
scanf("%d%d", &pos[i].x, &pos[i].y);
init();
getchar();
char ch;
while (~scanf("%c", &ch))
{
if (ch == 'O')//修复电脑
{
int w;
scanf("%d", &w);
sign[w] = 1;
for (int i = 1; i <= n; i++)
{
if (sign[i] && judge(i, w))//遍历之前已经修复,且距离符合条件的电脑。
merge(i, w);
}
}
else//判断电脑是否能交流
{
int u, v;
scanf("%d%d", &u, &v);
if (same(u, v))
printf("SUCCESS\n");
else
printf("FAIL\n");
}
getchar();
}
return 0;
}