POJ 2246 Wireless Network 【并查集 基础题】

POJ 2246 Wireless Network

题目链接:vjudge传送门

题目大意
给定N个坏掉的电脑以及坐标,规定通信距离为L,对每个电脑进行两个操作,维修或测试两个电脑是否可以通信,
给定若干个操作,判断其中的测试操作是否成功

具体思路:
对于O操作,每修理一个电脑就检测该电脑与所有被检测过的电脑之间能否通信,可以就把两个电脑加入同一个集合中
对于S操作,判断两台电脑是否在都修理过且在同一个集合中,满足就输出SUCCESS,否则输出FAIL

具体代码:

#include
#include
#include
#include
using namespace std;
int const N = 1005;
double const eps = 1e-5;
int fa[N];
int visit[N], cnt = 0;	//存放修理过的电脑编号
int beenOp[N];	//被修理过
int n, L;
struct Node {
     
	int x, y;
}point[N];
void init()
{
     
	for (int i = 1; i <= n; i++)
		fa[i] = i;
}
int find(int i)
{
     
	if (i != fa[i])
		fa[i] = find(fa[i]);
	return fa[i];
}
void unite(int i, int j)
{
     
	int x = find(i);
	int y = find(j);
	if (x == y)return;
	fa[x] = y;
}
bool cmpDis(int a, int b)	//查看两台电脑之间距离是否满足通信
{
     
	double len = sqrt((double)((point[a].x - point[b].x)*(point[a].x - point[b].x) + (point[a].y - point[b].y)*(point[a].y - point[b].y)));
	if (len - L<=eps)return true;
	return false;
}
int main()
{
     
	memset(beenOp, 0, sizeof(beenOp));
	scanf("%d%d", &n, &L);
	init();
	for (int i = 1; i <= n; i++)
		scanf("%d%d", &point[i].x, &point[i].y);
	getchar();
	char c;
	while (~scanf("%c ", &c))
	{
     
		if (c == 'O') {
     
			int opt;
			scanf("%d", &opt);
			for (int i = 0; i < cnt; i++) {
     
				if (cmpDis(visit[i], opt)) {
     
					unite(visit[i], opt);
				}
			}
			visit[cnt++] = opt;
			beenOp[opt] = 1;
		}
		else {
     
			int a, b;
			scanf("%d%d", &a, &b);
			if (beenOp[a] && beenOp[b] && find(a) == find(b)) {
     
				printf("SUCCESS\n");
			}
			else printf("FAIL\n");
		}
		getchar();
	}
	return 0;
}

你可能感兴趣的:(并查集,OJ题解)