POJ2236(Wireless Network)

题目传送门
POJ2236(Wireless Network)_第1张图片

题意

南亚发生了一次地震。ACM (Asia Cooperated Medical 亚洲联合医疗队) 已经为膝上型电脑搭建了一个无线网络,但受到了一次不可预知的余震攻击,因此网络中的所有电脑都被破坏了。电脑被逐台修复,网络逐步恢复了工作。由于受到硬件的约束,每台电脑只能与距离它不超过 d 米的其它电脑直接通信。但每台电脑可被看作其它两台电脑的通信中转点,也就是说,如果电脑 A 和电脑 B 可以直接通信,或存在一台电脑 C 既可与 A 也可与 B 通信,那么电脑 A 和电脑 B 之间就能够通信。 在处理网络修复的过程中,工作人员们在任何一个时刻,可以执行两种操作:维修一台电脑,或测试两台电脑是否能够通信。请您找出全部的测试操作。

思路

  1. s数组维护编号的根节点,s[i] = i;
  2. p数组存储每个点的坐标。
  3. map存储任意两点之间的距离,便于查询任意两点的距离。
  4. st集合维护已经重修好的计算机编号,每次修好一个计算机后,先去这个集合st中查找之前被修好的编号中能否和当前修好的计算机通信,如果能就把这两个计算机合并到一个并查集中买,维护完并查集之后一定要把这个点也加入到st集合中
  5. 查询两点能否通信直接去查找这两个节点是不是属于同一个根下,同根就能通信,否则不能。
//G++ 3500ms		C++ 1250ms,不知道为啥会有这么大的差距。
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
struct info{
	int x,y;
}p[1005];
int s[1005];				//存储父节点 
double map[1005][1005];		//索引距离 
set<int>st;					//修好的计算机编号 
void clear_set()
{
	st.clear(); 
	for(int i = 0;i < 1005;i++){
		s[i] = i;
	}
	for(int i = 0;i < 1005;i++){
		for(int j = i;j < 1005;j++){
			map[i][j] = map[j][i] = 25000;			//不可达 
		}
	}
}
double dist(info a,info b)				//计算距离
{
	return sqrt(1.0*((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y)));
}
int find_set(int x)
{
	int r = x;
	while(r != s[r]){
		r = s[r];
	}
	while(r != x){
		int j = s[x];
		s[x] = r;
		x = j;
	}
	return r;
}
int main()
{
	int n,d;
	while(~scanf("%d%d",&n,&d)){
		clear_set();
		for(int i = 1;i <= n;i++){
			scanf("%d%d",&p[i].x,&p[i].y);
		}
		for(int i = 1;i <= n;i++){
			for(int j = i+1;j <= n;j++){
				map[i][j] = dist(p[i],p[j]);
				map[j][i] = dist(p[i],p[j]);	
			}
			map[i][i] = 0;
		}
		char str[5];
		int x,y;
		set<int>::iterator ptr;
		while(~scanf("%s",str)){
			if(str[0] == 'O'){
				scanf("%d",&x);
				for(ptr = st.begin();ptr != st.end();ptr++){
					int y = *ptr;
					if(map[x][y] <= d){
						int fx = find_set(x);
						int fy = find_set(y);
						if(fx != fy){				//合到一棵树上 
							s[fx] = fy;
						}
					}
				}
				st.insert(x);					//一定要把当前修好的也加进去								
			}
			else{
				scanf("%d%d",&x,&y);
				int fx = find_set(x);
				int fy = find_set(y);
				if(fx == fy){				//同根下就能通信
					printf("SUCCESS\n");
				}
				else{			
					printf("FAIL\n");		
				}
			}
		}
	}
	return 0;
}

愿你走出半生,归来仍是少年~

你可能感兴趣的:(并查集)