zoukankan      html  css  js  c++  java
  • 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
    ");
                else printf("FAIL
    ");
            }
        }
    }
    
  • 相关阅读:
    0039. Combination Sum (M)
    imei和imsi
    APP网络测试要点和弱网模拟
    Git常用命令
    HTTP host头
    与apk签名有关的那些概念与命令
    你应该知道的运维术语
    nginx、fastCGI、php-fpm关系梳理
    adb连接手机报错解决方案汇总(win7)
    Android DVM
  • 原文地址:https://www.cnblogs.com/Tianwell/p/11194899.html
Copyright © 2011-2022 走看看