【并查集变形】POJ 2236——Wireless Network

题目链接:点击打开链接

并查集的一个变形问题,给出一些电脑(坏了的电脑)和允许通讯的电脑的最大距离,然后用O功能-修复一些电脑,S功能查询两个电脑能否正常通讯。

若想使电脑正常通讯,需要满足两个条件:

1、两台电脑的距离要比允许的最大值小。

2、两台电脑必须都是修复好的。

比起一般的并查集问题,多使用了一个距离的判断参数,来判断可能出现的距离。

好长时间没用并查集了,最初的时候居然漏掉初始化。。还好发现的比较早,然后初始化的时候都初始化成了1,判断的时候又根据印象随手写了一个,囧。下次一定要注意并查集的初始化语句,ORZ。。


#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <cmath>
using namespace std;

class point
{
	public:
		int x;
		int y;
		int vis;
};

int numpack[20005];
point dispack[20005];


int search_father(int x)
{
	int result=x;
	while(result!=numpack[result])
	{
		result=numpack[result];
	}
	return result;
}

void merge(int a,int b)
{
	int ka=search_father(a);
	int kb=search_father(b);
	if(ka!=kb)
	{
		numpack[ka]=kb;
	}
}

double isdis(int pos1,int pos2)
{
	return sqrt((double)(dispack[pos1].x-dispack[pos2].x)*(dispack[pos1].x-dispack[pos2].x)+(dispack[pos1].y-dispack[pos2].y)*(dispack[pos1].y-dispack[pos2].y));
}


void init_pro()
{
	for(int i=1;i<20005;i++)
	{
		numpack[i]=i;
	}
}

int main()
{
	int testcase,tar;
	string command;
	double dismax;         //注意不是int... 
	cin>>testcase>>dismax;
	init_pro();
	for(int i=1;i<=testcase;i++)
	{
		scanf("%d%d",&dispack[i].x,&dispack[i].y);
		dispack[i].vis=0;
	}
	while(cin>>command)
	{
		if(command=="O")
		{
			scanf("%d",&tar);
			dispack[tar].vis=1;
			for(int i = 1;i <= testcase;i++)
			{
				if(i!=tar && isdis(i,tar)<=dismax && dispack[i].vis){	//若刚修好的电脑与另一台已经修好电脑的距离不超过d,那么他们之间就可以通信
					merge(i,tar);
			}
		}
		}
		else
		{
			int a,b;
			scanf("%d %d",&a,&b);
			if(search_father(a)==search_father(b)) 
				printf("SUCCESS\n");		//属于同一个集合就可以通信
			else printf("FAIL\n");
		}
	}
	
	return 0;
}


你可能感兴趣的:(【并查集变形】POJ 2236——Wireless Network)