POJ-2236 Wireless Network(并查集)

题目

东南亚发生地震。ACM(亚洲合作医疗队)与膝上电脑建立了无线网络,但意外的余震袭击了网络中的所有电脑。电脑一台一台修好,网络也渐渐开始恢复了。由于硬件限制,每台计算机只能直接与距离它不超过d米的计算机通信。但是每台计算机都可以看作是其他两台计算机之间通信的中介,也就是说,如果计算机 A 和计算机 B 可以直接通信,或者有一台计算机 C 可以同时与 A 和计算机通信,那么计算机 A 和计算机 B 就可以通信。 B.

在修复网络的过程中,工人每时每刻都可以进行两种操作,修复一台计算机,或者测试两台计算机是否可以通信。你的工作是回答所有的测试操作。

输入

第一行包含两个整数 N 和 d(1 <= N <= 1001, 0 <= d <= 20000)。这里 N 是计算机的数量,从 1 到 N 编号,D 是两台计算机可以直接通信的最大距离。在接下来的 N 行中,每行包含两个整数 xi, yi (0 <= xi, yi <= 10000),这是 N 台计算机的坐标。从第(N+1)行到输入结束,有操作,一一进行。每行包含以下两种格式之一的操作:
1. "O p" (1 <= p <= N),表示修复计算机 p。
2. "S p q" (1 <= p, q <= N),表示测试计算机p和q是否可以通信。

输入不会超过300000行。

输出

对于每个测试操作,如果两台计算机可以通信,则打印“SUCCESS”,否则打印“FAIL”。

样本输入

4 1 
0 1 
0 2 
0 3 
0 4 
O 1 
O 2 
O 4 
S 1 4 
O 3 
S 1 4

样本输出

FAIL
SUCCESS

AC代码 

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int n,m;
int f[1010];
int vis[1010][1010],fl[1010];		//vis标记两点间距离是否小于d,fl标记电脑是否被修过 
float x[1010],y[1010];
int getf(int v)
{
	if(f[v]==v)
		return v;
	else
	{
		f[v]=getf(f[v]);
		return f[v];
	}
} 
void merge(int u,int v)
{
	int t1,t2;
	t1=getf(u);
	t2=getf(v);
	if(t1!=t2)
		f[t2]=t1;
}
int main()
{
	int n,d,i,j;
	cin>>n>>d;
	for(int i=1;i<=n;i++)		//每个节点的根节点初始化为自己 
		f[i]=i;
	for(i=1;i<=n;i++)
	{
		cin>>x[i]>>y[i];
	}
	for(i=1;i<=n;i++)
	{
		for(j=i;j<=n;j++)
		{
			if((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])<=d*d)
				vis[i][j]=vis[j][i]=1;					//如果这个点在距离d之内就标记 
		}
	}
	char c;
	int a,b;
	while(~scanf("%c",&c))
	{
		if(c=='O')
		{
			cin>>a;
			fl[a]=1;		//标记修过的电脑a 
			for(i=1;i<=n;i++)
				if(i!=a&&vis[a][i]&&fl[i])			//a和i在距离d之内,且a和i是修过的电脑 
					merge(a,i);
		}
		if(c=='S')
		{
			cin>>a>>b;
			if(getf(a)==getf(b))					//如果根节点一样就表示a和b连通
				cout<<"SUCCESS"<<endl;
			else
				cout<<"FAIL"<<endl; 
		} 
	} 
	return 0;
}

努力努力再努力( ⊙ o ⊙ )

Supongo que te gusta

Origin blog.csdn.net/zz_xun/article/details/119937847
Recomendado
Clasificación