关于路径压缩与按秩合并

P3367 【模板】并查集

SuperCowHorse @ 2022-08-19 19:33:36

我记得只有路径压缩并查集的复杂度是 O(n\log n),路径压缩+按秩合并好像是 O(n\alpha(n)) 的,但为什么两种写法时间相差不多?

记录:只有路径压缩

路径压缩+按秩合并

代码:

路径压缩:

#include<bits/stdc++.h>
using namespace std;
int n,m,z,x,y;
int fa[10005];
struct bcj{
    int fa[10005];
    void init(){
        for(int i=1;i<=n;++i)
            fa[i]=i;
    }
    int find(int x){
        if(x!=fa[x]) fa[x]=find(fa[x]);
        return fa[x];
    }
    void Union(int x,int y){
        int a=find(x);
        int b=find(y);
        if(a!=b)
            fa[b]=a;
    }
}b;
int main()
{
    scanf("%d%d",&n,&m);
    b.init();
    while(m--)
    {
        scanf("%d%d%d",&z,&x,&y);
        if(z==1)
            b.Union(x,y);
        else
        {
            if(b.find(x)==b.find(y)) printf("Y\n");
            else printf("N\n");
        }
    }
    return 0;
}

路径压缩+按秩合并:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e4+5;
int n,m;
struct bcj{
    int fa[maxn],g[maxn];
    void init(){
        for(int i=1;i<=n;++i)
            fa[i]=i,g[i]=1;
    }
    int find(int x){return fa[x]==x?fa[x]:fa[x]=find(fa[x]);}
    void merge(int x,int y){
        int u=find(x);
        int v=find(y);
        if(u==v) return;
        if(g[u]<g[v]) swap(u,v);
        fa[v]=fa[u];
        g[u]+=g[v];
    }
    bool check(int u,int v){return find(u)==find(v);}
}b;
signed main(){
    scanf("%d%d",&n,&m);
    b.init();
    while(m--){
        int op,u,v;
        scanf("%d%d%d",&op,&u,&v);
        if(op==1)
            b.merge(u,v);
        else
            putchar(b.check(u,v)?'Y':'N'),putchar('\n');
    }
    return 0;
}

难道我学假了???


by Compound_Interest @ 2022-08-19 19:57:54

@Fish9块1 不应该是同时使用路径压缩和按秩合并可以看成O(1)


by makerlife @ 2022-08-19 19:59:37

@chenye3

把路径压缩和按秩合并合起来一起使用的话可以把查询复杂度下降到O(α(n))

其中 \alpha (n) 可以看作时一个常数

所以路径压缩+按秩合并可以看成是 O(1)


by Fish9块1 @ 2022-08-19 19:59:51

@x17875487211 随机数据情况下


by ConanOI_Official @ 2022-08-19 20:01:10

这两种东西随机数据下都跑的挺快的吧,不构造数据不太看得出差别。

其实构造了数据以后 O(q\log n)O(q\alpha(n)) 实际表现也不会差很大的,没怎么见到过卡这个复杂度的题。


by 昒昕 @ 2022-08-19 20:01:27


by Fish9块1 @ 2022-08-19 20:03:35

正确的,卡了也没什么用


by SuperCowHorse @ 2022-08-19 20:11:46

好吧谢谢各位 dalao orz


by _XHY20180718_ @ 2022-08-23 23:05:59

@chenye3 数据太水感觉不出来。


by _XHY20180718_ @ 2022-08-23 23:13:00

@x17875487211 应该是 O(a(n)) 的,请不要乱说。


by Compound_Interest @ 2022-08-24 08:15:42

@xiehuiying 知道O(a(n))是什么量级吗,是反Ackermann函数,在一般情况下都<4

log*$(2的 65536次方)$=5

但是你竞赛能的计算量能达到2的65536次方这个量级吗。

2的65536大于宇宙的原子个数,怕是工程上也很难遇到这种量级的计算量吧

在质疑别人之前最好自己先查好资料


上一页 | 下一页