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");
        }
    }
}

 

posted @ 2019-07-16 14:51  Tianwell  阅读(125)  评论(0编辑  收藏  举报