• FJUT ACM 2351 T^T的图论


    T^T的图论

    TimeLimit:3000MS  MemoryLimit:256MB
    64-bit integer IO format:%lld
     
    Problem Description

    有一个坐标系,坐标系上有n个点,在同一行或同一列上的任意两点称为关联的,并且关联属性是可传递的,即A和B关联,B和C关联,则可认为A和C关联,现在问图中是否任意两点都是关联的。

    Input

    n>=2 && n<=50万

    每个点的坐标x、y满足 1<=x、y<=50000

    Output

    如果是关联的,输出YES,否则,输出NO

    SampleInput
    2
    1 1
    3 3
    3
    1 1
    1 3
    3 3
    
    SampleOutput
    NO
    YES

    【思路】:感觉就是一题并查集的题,就是多了个排序操作而已,我先建了个结构体去储存
    x和y,先对x进行排序,再对x相同的进行并查集的连接,接着再对y进行排序,再对y相同的
    进行排序,然后再对y相同的进行并查集的连接,然后我wa了一发,为什么呢,因为我发现每次
    排序后i的值发生变化,gg了,然后我就再加了个变量flag来标记,令flag=i;然后连接的时候
    使用flag,就成功ac了一发。
    附上代码:
    #include<bits/stdc++.h>
    #define MAXN 500005
    using namespace std;
    typedef struct MYINT
    {
        int x;
        int y;
        int flag;
    } myint;
    myint math[MAXN];
    int pre[MAXN];
    void Init()
    {
        for(int i=0; i<MAXN; i++)
        {
            pre[i]=i;
        }
    }
    int acfind(int x)
    {
        return pre[x]==x?x:pre[x]=acfind(pre[x]);
    }
    int unionjoin(int x,int y)
    {
        int a;
        int b;
        a=acfind(x);
        b=acfind(y);
        if(a!=b)
            pre[b]=a;
    }
    bool cmp1(myint a,myint b)
    {
        return a.x>b.x;
    }
    bool cmp2(myint a,myint b)
    {
        return a.y>b.y;
    }
    int main()
    {
        int n;
        while(~scanf("%d",&n))
        {
            Init();
            memset(math,0,sizeof(math));
            for(int i=0; i<n; i++)
                {scanf("%d %d",&math[i].x,&math[i].y);
                math[i].flag=i;
                }
            sort(math,math+n,cmp1);
            for(int i=1; i<n; i++)
            {
                if(math[i].x==math[i-1].x)
                    unionjoin(math[i].flag,math[i-1].flag);
            }
            sort(math,math+n,cmp2);
            for(int i=1; i<n; i++)
            {
                if(math[i].y==math[i-1].y)
                    unionjoin(math[i].flag,math[i-1].flag);
            }
            int ans=acfind(0);
            int flag=0;
            for(int i=1; i<n; i++)
            {
                if(ans!=acfind(i))
                {
                    printf("NO
    ");
                    flag=1;
                    break;
                }
            }
            if(flag==0)
                printf("YES
    ");
        }
        return 0;
    }
  • 相关阅读:
    【实验吧】藏在图片中的秘密
    pwntools各使用模块简介
    【笔记】shellcode相关整理
    【pwnable】asm之write up
    【实验吧】转瞬即逝write up
    利用wireshark任意获取qq好友IP实施精准定位
    【实验吧】逆向1000
    【实验吧】逆向rev50
    pwnable.kr brainfuck之write up
    JavaScript获取后台C#变量以及调用后台方法
  • 原文地址:https://www.cnblogs.com/qq136155330/p/8782770.html
Copyright © 2020-2023  润新知