zoukankan      html  css  js  c++  java
  • POJ

    An earthquake takes place in Southeast Asia. The ACM (Asia Cooperated Medical team) have set up a wireless network with the lap computers, but an unexpected aftershock attacked, all computers in the network were all broken. The computers are repaired one by one, and the network gradually began to work again. Because of the hardware restricts, each computer can only directly communicate with the computers that are not farther than d meters from it. But every computer can be regarded as the intermediary of the communication between two other computers, that is to say computer A and computer B can communicate if computer A and computer B can communicate directly or there is a computer C that can communicate with both A and B.

    In the process of repairing the network, workers can take two kinds of operations at every moment, repairing a computer, or testing if two computers can communicate. Your job is to answer all the testing operations.
    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.

    The input will not exceed 300000 lines.
    Output
    For each Testing operation, print “SUCCESS” if the two computers can communicate, or “FAIL” if not.
    Sample Input
    4 1
    0 1
    0 2
    0 3
    0 4
    O 1
    O 2
    O 4
    S 1 4
    O 3
    S 1 4
    Sample Output
    FAIL
    SUCCESS

    题意:有N台电脑一开始全是坏掉的,用O 操作修复第i台电脑,用S操作检查x和y号电脑是否互联,其中两台好的电脑如果距离小于D则可以互联,每台电脑的标号是他输入时的下标,现在输入所有电脑的坐标,查询两两电脑之间是否可以直接或间接互联

    一开始看到坐标以为是图论,后来发现因为电脑之间可以间接联通,因此能够在一定距离内修好并连同的电脑可以作为一个桥梁使附近剩下的电脑尽肯能的联通,因此是类似于并查集中收揽集合的过程,而检查是否互联也可以用并查集中find函数实现。

    首先输入所有电脑的坐标,并计算两两之间的建立,如果两两距离小于D还能继续将其列入可能互联的待选列表中(vector)

    然后修电脑的操作将电脑修好的标记标为true,并通过之前的待选列表将刚修好的电脑尽可能的利用并查集的join函数与其他电脑互联。

    查询时只需check两两电脑是否在同一个集合中即可判断是否互联

    #include<stdio.h>///并查集
    #include<set>
    #include<math.h>
    #include<string>
    #include<string.h>
    #include<iostream>
    #include<queue>
    #include<vector>
    #define LL long long
    using namespace std;
    struct com
    {
        double x,y;
    } a[1004];
    int n,t,ans,d,tmp;
    double dis[1005][1008];
    vector<int>v[1005];
    bool vis[1005];
    int x,y;
    int zz[1005];
    int finds(int x)
    {
        int r=x,t;
        while(r!=zz[r])
        {
            t=r;
            r=zz[r];
            zz[t]=zz[r];
        }
        return r;
    }
    void join(int a,int b)
    {
        int fa=finds(a),fb=finds(b);
        if(fa!=fb)
        {
            zz[fa]=fb;
        }
    }
    int main()
    {
        while(scanf("%d%d",&n,&d)!=EOF)
        {
            memset(vis,false,sizeof(vis));
            memset(dis,0x3f,sizeof(dis));
            for(int i=1;i<=n;i++)v[i].clear();
            for(int i=1;i<=n;i++)zz[i]=i;
            for(int i=1; i<=n; i++)
            {
                scanf("%lf%lf",&a[i].x,&a[i].y);
                for(int j=1; j<i; j++)
                {
                    dis[i][j]=dis[j][i]=sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y));
                    if(dis[i][j]<=d)///将每个电脑周围的可选距离的电脑收入vector中待选
                    {
                        v[i].push_back(j);
                        v[j].push_back(i);
                    }
                }
            }
            char flag[3];
            while(scanf("%s",flag)!=EOF)
            {
                if(flag[0]=='O')
                {
                    scanf("%d",&tmp);
                    vis[tmp]=true;
                    for(int i=0; i<v[tmp].size(); i++)
                    {
                        if(vis[v[tmp][i]])
                        {
    //                        printf("%d-------%d
    ",vis[v[tmp][i]],v[tmp][i]);
                            join(v[tmp][i],tmp);
                        }
                    }
    //                for(int i=1;i<=n;i++)
    //                {
    //                    printf("%d====>%d
    ",i,zz[i]);
    //                }
                }
                else
                {
                    scanf("%d%d",&x,&y);
                    if(finds(x)==finds(y))
                    {
                        printf("SUCCESS
    ");
                    }
                    else
                    {
                        printf("FAIL
    ");
                    }
                }
            }
        }
        return 0;
    }
    
    
  • 相关阅读:
    基于吉日嘎底层架构的Web端权限管理操作演示-日志管理
    基于吉日嘎底层架构的Web端权限管理操作演示-组织机构管理
    基于吉日嘎底层架构的Web端权限管理操作演示-菜单模块管理
    基于吉日嘎底层架构的Web端权限管理操作演示-角色管理
    基于吉日嘎底层架构的Web端权限管理操作演示-用户管理
    扩展吉日嘎拉的用户角色管理,让用户角色编码和名称在一个组织里面唯一
    Redis 3.2.100 Windows 32位下载
    C#开发中Windows域认证登录2016(扩展吉日嘎拉GPM系统V4.2)
    JVM对象
    将博客搬至CSDN
  • 原文地址:https://www.cnblogs.com/kuronekonano/p/11135832.html
Copyright © 2011-2022 走看看