zoukankan      html  css  js  c++  java
  • GPLT L2-024 部落 (并查集)

    N ≤ 104,输入如下数据如果没有路径压缩可能会超时。

    10000

    2 1 2

    2 3 4

    2 5 6

    ……

    2 9997 9998

    2 9999 10000

    2 9999 9997

    ……

    2 5 3

    2 3 1

    10000

    10000 10000

    ……

    10000 10000

    但事实上,两种写法的运行时间都为 50ms 左右。

    ${O_{left( n^2/2 ight)}}$:

    #include <bits/stdc++.h>
    using namespace std;
    
    const int M=11000;
    
    int fri[M];
    bool vis[M];
    
    int Find(int x){
        while(x!=fri[x]) x=fri[x];
        return x;
    }
    
    void Union(int A,int B){
        int friA=Find(A);
        int friB=Find(B);
        if(friA>friB) fri[friA]=friB;
        if(friB>friA) fri[friB]=friA;
    }
    
    int main()
    {
        for(int i=0;i<M;i++) fri[i]=i;
        int n;cin>>n;
        for(int i=0;i<n;i++){
            int k;cin>>k;
            int a[k];
            for(int j=0;j<k;j++){
                cin>>a[j];
                vis[a[j]]=true;
                if(j) Union(a[j],a[j-1]);
            }
        }
        int people=0,tribe=0;
        for(int i=0;i<M;i++){
            if(vis[i]) ++people;
            if(vis[i]&&fri[i]==i) ++tribe;
        }
        cout<<people<<" "<<tribe<<"
    ";
        int q;cin>>q;
        for(int i=0;i<q;i++){
            int a,b;cin>>a>>b;
            cout<<(Find(a)==Find(b)?"Y":"N")<<"
    ";
        }
        return 0;
    }

    ${O_{left( n ight)}}$:

    #include <bits/stdc++.h>
    using namespace std;
    
    const int M=11000;
    
    int fri[M];
    bool vis[M];
    
    int Find(int x){
        int f=x;
        while(f!=fri[f]) f=fri[f];
        int a=x,b;
        while(a!=fri[a]) b=fri[a],fri[a]=f,a=b; 
        return f;
    }
    
    void Union(int A,int B){
        int friA=Find(A);
        int friB=Find(B);
        if(friA>friB) fri[friA]=friB;
        if(friB>friA) fri[friB]=friA;
    }
    
    int main()
    {
        for(int i=0;i<M;i++) fri[i]=i;
        int n;cin>>n;
        for(int i=0;i<n;i++){
            int k;cin>>k;
            int a[k];
            for(int j=0;j<k;j++){
                cin>>a[j];
                vis[a[j]]=true;
                if(j) Union(a[j],a[j-1]);
            }
        }
        int people=0,tribe=0;
        for(int i=0;i<M;i++){
            if(vis[i]) ++people;
            if(vis[i]&&fri[i]==i) ++tribe;
        }
        cout<<people<<" "<<tribe<<"
    ";
        int q;cin>>q;
        for(int i=0;i<q;i++){
            int a,b;cin>>a>>b;
            cout<<(Find(a)==Find(b)?"Y":"N")<<"
    ";
        }
        return 0;
    }
  • 相关阅读:
    碰撞检测 :Polygon
    碰撞检测 :Line
    碰撞检测 :Rectangle
    碰撞检测:Point
    Canvas 绘制 1 px 直线模糊(非高清屏)的问题
    threading之线程的开始,暂停和退出
    win10利用hexo+gitee搭建博客
    Fullscreen API与DOM监听API
    <el-input>只能输入数字,保留两位小数
    谷歌浏览器查看gitee和github代码的插件
  • 原文地址:https://www.cnblogs.com/Kanoon/p/12509866.html
Copyright © 2011-2022 走看看