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;
    }
  • 相关阅读:
    grunt in webstorm
    10+ Best Responsive HTML5 AngularJS Templates
    响应式布局
    responsive grid
    responsive layout
    js event bubble and capturing
    Understanding Service Types
    To add private variable to this Javascript literal object
    Centering HTML elements larger than their parents
    java5 新特性
  • 原文地址:https://www.cnblogs.com/longl/p/7279977.html
Copyright © 2011-2022 走看看