POJ2236 Wireless Network 并查集

本文介绍了一个使用并查集算法解决电脑间通信问题的方法。通过修复指令更新电脑状态,并利用查询指令判断两台电脑是否能通信。文章详细解释了如何通过计算距离判断两台电脑是否满足通信条件,并通过并查集维护电脑间的连接状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:现有n台需要修复的电脑(编号1~N),某两台电脑之间是否能通信的标准有两个。第一:两台电脑相距的距离小于d;第二,两台电脑可以通过其他电脑通信。

输入信息:首先会给出电脑的数量N和额定距离d,然后会给出各台电脑的坐标xi和yi。然后会给出对电脑的两种操作,分别是修复和查询。修复命令为O i,表示修复第i台电脑;查询操作为S i j,表示查询第i台电脑和第j台电脑之间是否能够通信。

输出信息:再输入查询命令时需要输出“SUCCESS”或者“FAIL”来回答这两台电脑是否能够通信。

思路:首先,这里有个隐含的条件,如果两台电脑可以通信,这两台电脑必须是已经被修复了的。其次,如果某些电脑之间可以互相通信,则可以将他们看作一个集合。查询某两台电脑是否属于一个集合的问题合一用并查集很好的解决。步骤为:1,修复某台电脑时,依次检查其他各台电脑,将小于额定距离且已经被修复的电脑加入同一集合。2,查询某两台电脑是否能够通信时,直接检查这两台电脑是否属于同一集合,若属于同一集合,则能够通信;若不属于,则不能通信。

#include <stdio.h>
#include <iostream>
#include <math.h>

using namespace std;
typedef pair<int, int> P;

int par[20000],rank[20000];
int N,D;
P point[1001];									//各电脑坐标
int state[1001];								//各电脑修复状态,已修复为1,未修复为0

void init(int n)
{
	for(int i = 0; i < n; i++)
	{
		par[i]=i;
		rank[i]=0;
	}
}
int find(int x)
{
	if(par[x] == x)
		return x;
	else
		return par[x]=find(par[x]);
}
void unite(int x,int y)
{
	x=find(x);
	y=find(y);
	if(x == y)
		return;
	if(rank[x] < rank [y])
		par[x] = y;
	else
	{
		par[y] = x;
		if(rank[x] == rank[y])
			rank[x]++;
	}
}
bool same(int x,int y)
{
	return find(x) == find(y);
}
//检查某两台电脑之间的距离是否符合要求,若符合则返回1;若不符合返回0
int dis(int m_i , int m_j)
{
	int ret, delta_x, delta_y;
	delta_x = pow(point[m_i].first - point[m_j].first, 2);
	delta_y = pow(point[m_i].second - point[m_j].second, 2);
	if(delta_x + delta_y <= D*D)
		return 1;
	else return 0;
}

int main()
{
	cin >> N >> D;
	init(N);
	int tmp_i, tmp_j;
	P tmp_p;
	for(int i = 1; i <= N; i++)				//保存各电脑坐标
	{
		cin >> tmp_i >> tmp_j;
		tmp_p = make_pair(tmp_i, tmp_j);
		point[i] = tmp_p;
	}
	char opera;
	int num_1, num_2;
	while(cin >> opera)
	{
		if(opera == 'O')
		{
			cin >> num_1;
			state[num_1] = 1;
			for(int i = 1; i <= N; i++)			//依次检查其他各台电脑,将小于额定距离且已经被修复的电脑加入同一集合
			{
				if(i == num_1)
					continue;
				if(state[i] && state[num_1] && !same(i, num_1) && dis(i, num_1))
					unite(i, num_1);
			}
		
		}
		else if(opera == 'S')		//检查这两台电脑是否属于同一集合,若属于同一集合,则能够通信;若不属于,则不能通信
		{
			cin >> num_1 >> num_2;
			if(same(num_1, num_2))
				cout<< "SUCCESS" << endl;
			else cout<< "FAIL" << endl;
		}
	}
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值