zoukankan      html  css  js  c++  java
  • T^T的图论

     
    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


    一开始超时了

    #include<cstdio>
    using namespace std;
    const int maxn=6000000;
    int pre[maxn];
    struct Node
    {
        int x,y;
    } node[maxn];
    int find(int x)
    {
        int r=x;
        while(r!=pre[r])
            r=pre[r];
        int i=x,j;
        while(pre[i]!=r)
        {
            j=pre[i];
            pre[i]=r;
            i=j;
        }
        return r;
    
    }
    int join(int x,int y)
    {
        int fx=find(x),fy=find(y);
        if(fx!=fy)
            pre[fx]=fy;
    
    }
    int main()
    {
    
        int n,x,y;
        while(~scanf("%d",&n))
        {
            for(int i=1; i<=n; i++)
                pre[i]=i;
            for(int i=1; i<=n; i++)  
            {
                scanf("%d%d",&node[i].x,&node[i].y);
                for(int j=1; j<i; j++)
                    if(node[i].x==node[j].x||node[i].y==node[j].y)
                        join(i,j);
            }
            int p=find(1),flag=1;
            for(int i=2; i<=n; i++)
            {
                if(p!=find(i)){
                    flag=0;
                    break;
                }
            }
            if(flag)puts("YES");
            else puts("NO");
    
        }
    
        return 0;
    }
    
    

    后来分别对x,y排序,这样x,y相同的就会聚在一起,卡时间AC了

    
    
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int maxn=6000000;
    int pre[maxn];
    struct Node
    {
        int index,x,y;
    } node[maxn];
    bool cmp1(Node a,Node b)
    {
        return a.x<b.x;
    }
    bool cmp2(Node a,Node b)
    {
        return a.y<b.y;
    }
    
    int find(int x)
    {
        int r=x;
        while(r!=pre[r])
            r=pre[r];
        int i=x,j;
        while(pre[i]!=r)
        {
            j=pre[i];
            pre[i]=r;
            i=j;
        }
        return r;
    }
    
    int join(int x,int y)
    {
        int fx=find(x),fy=find(y);
        if(fx!=fy)
            pre[fx]=fy;
    
    }
    int main()
    {
    
        int n,x,y;
       while(~scanf("%d",&n))
       {
    
            for(int i=1; i<=n; i++)
                pre[i]=i;
    
            for(int i=1; i<=n; i++)
            {
                node[i].index=i;
                scanf("%d%d",&node[i].x,&node[i].y);
            }
            /// 对x排序
            sort(node+1,node+n+1,cmp1);
            for(int i=2;i<=n;i++)
            {
                if(node[i].x==node[i-1].x)
                {
                    join(node[i].index,node[i-1].index);
                }
            }
            /// 对Y排序
            sort(node+1,node+n+1,cmp2);
            for(int i=2;i<=n;i++)
            {
                if(node[i].y==node[i-1].y)
                {
                    join(node[i].index,node[i-1].index);
                }
            }
    
            int p=find(1),flag=1;       ///找1的祖先应该 find(1),而不是 pre[1],pre[]是给find函数用的
            for(int i=2; i<=n; i++)
            {
                if(p!=find(i))
                {
                    flag=0;
                    break;
                }
            }
            if(flag)puts("YES");
            else puts("NO");
    
        }
    
        return 0;
    }
  • 相关阅读:
    vim 插件之commentary
    vim-进入插入模式快捷键
    adb logcat 使用
    操作excel脚本练习
    python-openpyxl安装
    python-excel操作之xlrd
    adb-端口被占用解决办法(win)
    打不开微信分享的链接
    在BUG分支下创建分支,开发后合并到bus分支
    css缓存问题
  • 原文地址:https://www.cnblogs.com/longl/p/7279977.html
Copyright © 2011-2022 走看看