POJ-2236 Wireless Network (并查集)
Input
The first line contains two integers N and d (1 <= N <= 1001, 0 <= d <= 20000). Here N is the number of computers, which are numbered from 1 to N, and D is the maximum distance two computers can communicate directly. In the next N lines, each contains two integers xi, yi (0 <= xi, yi <= 10000), which is the coordinate of N computers. From the (N+1)-th line to the end of input, there are operations, which are carried out one by one. Each line contains an operation in one of following two formats:
1. "O p" (1 <= p <= N), which means repairing computer p.
2. "S p q" (1 <= p, q <= N), which means testing whether computer p and q can communicate.
output
The input will not exceed 300000 lines.
For each Testing operation, print "SUCCESS" if the two computers can communicate, or "FAIL" if not.
题意:有N台电脑,编号1-n. 然后d为两台电脑之间的最小连接距离:给出当两台电脑坐标距离小于d时,两台电脑可以直接连接。 电脑之间也可以间接连接:例如B-C ,A-B 则可得A-C
然后在N台坐标输入结束后执行操作 O p 激活电脑p,S p q判断p q 是否连接(输入判断不超过300000行)
思路:连接问题可以看做所有连通的元素属于一个集合中。然后就是关于unite(Union)和find函数的修改,写一个判断距离条件的函数,以及如何存储问题:
通过结构体数组来记录下标,在输入结束后开始遍历周围符合条件的坐标点将其关联(即符合距离条件),在进行操作unite时就判断是否符合距离条件以及周围的点是否被激活
完整题解:
#include<iostream>
#include<cstdio>
#include<cstring>
const int maxn = 1005;
using namespace std;
int pre[maxn],p[maxn][2];
bool dis[maxn][maxn],vis[maxn];
long long getdis(int x1,int y1,int x2,int y2)
{
//距离公式
return ((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
int find(int x)
{
if(x!=pre[x]) return pre[x] = find(pre[x]);
else return pre[x];
}
void unite(int x,int y)
{
int fx=find(x),fy=find(y);
if(fx!=fy)
{
pre[fx]=fy;
}
}
bool judge(int x,int y){
if(find(x)==find(y)) return true;
else return false;
}
int main()
{
int n,d,x,y;
char s;
memset(vis,false,sizeof(vis));
memset(dis,false,sizeof(dis));
scanf("%d%d",&n,&d);
for(int i=0; i<=n; i++) pre[i]=i;
for(int i=1; i<=n; i++)
{
scanf("%d%d",&p[i][0],&p[i][1]);
}
for(int i=1; i<=n; i++) //把每个点周围都关联起来;
{
for(int j=i; j<=n; j++)
{
if(getdis(p[i][0],p[i][1],p[j][0],p[j][1])<=d*d)
dis[i][j]=dis[j][i]=true;//先把dis符合条件关联
}
}
while(cin>>s)
{
if(s=='O')
{
scanf("%d",&x);
vis[x]=true;
for(int i=1; i<=n; i++)
{
if(i!=x&&vis[i]&&dis[i][x])
{
unite(i,x);
}
}
}
else
{
scanf("%d%d",&x,&y);
if(judge(x,y)) printf("SUCCESS\n");
else printf("FAIL\n");
}
}
}

浙公网安备 33010602011771号