zoukankan      html  css  js  c++  java
  • Yangk's 并查集-模板

    //并查集-都要给fa赋初值!!
    //======================================
    /*递归版路径压缩*/

    int fa[maxn];
    int find(int x)
    {
        return fa[x]==x?x:fa[x]=find(fa[x]);
    }
    void merge(int x,int y)
    {
        fa[find(x)]=find(y);
    }

    //======================================
    /*循环版路径压缩,循环稍快一点*/

    int fa[maxn];
    int find(int x)
    {
        while(x!=fa[x]) x=fa[x]=fa[fa[x]];
        return x;
    }
    void merge(int x,int y)
    {
        fa[find(x)]=find(y);
    }

    //======================================
    /*按秩合并*/
    /*把深度小的并到深度大的上,保证深度不会增加*/

    int fa[maxn],rank[maxn];
    int find(int x)
    {
        return fa[x]==0?x:find(fa[x]);
    }
    void merge(int x,int y)
    {
        x=find(x);
        y=find(y);
        if(x!=y)
        {
            if(rank[x]<=rank[y])fa[x]=y,rank[y]=max(rank[y],rank[x]+1);
            else fa[y]=x,rank[x]=max(rank[x],rank[y]+1);
        }
    }

    //======================================

    //可持久化并查集
    /*每个版本并查集的深度不同,需要开可持久化数组记录每个版本的dep
    两个可持久化数组分别维护fa和dep
    注意优化要选择按秩合并,不要路径压缩

    1,合并a,b

    2,回到第k个版本

    3,询问a,b是不是在一个集合里

    每次操作都算作一个版本*/

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define lowbit(a) ((a)&-(a))
    #define clean(a,b) memset(a,b,sizeof(a))
    const int mod = 1e9 + 7;
    const int inf=0x3f3f3f3f;
    int _;
    //==================================================================
    const int maxn = 2e5+9;
    int tot,cnt,rootfa[maxn],rootdep[maxn],n;
    struct node 
    {
        int l,r,val;
    }hjt[maxn*40*2];
    void build(int l,int r,int &now)
    {
        now=++cnt;
        if(l==r) 
        {
            hjt[now].val=++tot;
            return ;
        }
        int mid=(l+r)>>1;
        build(l,mid,hjt[now].l);
        build(mid+1,r,hjt[now].r);
    }
    void modify(int l,int r,int var,int &now,int pos,int num)
    {
        now=++cnt;
        hjt[now]=hjt[var];
        if(l==r) 
        {
            hjt[now].val=num;
            return ;
        }
        int mid=(l+r)>>1;
        if(pos<=mid) modify(l,mid,hjt[var].l,hjt[now].l,pos,num);
        else modify(mid+1,r,hjt[var].r,hjt[now].r,pos,num);
    }
    int query(int l,int r,int now,int pos)
    {
        if(l==r)  return hjt[now].val;
        int mid=(l+r)>>1;
        if(pos<=mid) return query(l,mid,hjt[now].l,pos);
        else return query(mid+1,r,hjt[now].r,pos);
    }
    int find(int var,int x)
    {
        int fx=query(1,n,rootfa[var],x);
        return fx==x?x:find(var,fx);
    }
    void merge (int var,int x,int y)
    {
        x=find(var-1,x);
        y=find(var-1,y);
        if(x==y) 
        {
            rootfa[var]=rootfa[var-1];
            rootdep[var]=rootfa[var-1];
        }
        else 
        {
            int dpx=query(1,n,rootdep[var-1],x);
            int dpy=query(1,n,rootdep[var-1],y);
            if(dpx<dpy)
            {
                modify(1,n,rootfa[var-1],rootfa[var],x,y);
                rootdep[var]=rootdep[var-1];
            }
            else if(dpx>dpy)
            {
                modify(1,n,rootfa[var-1],rootfa[var],y,x);
                rootdep[var]=rootdep[var-1];
            }
            else 
            {
                modify(1,n,rootfa[var-1],rootfa[var],x,y);
                modify(1,n,rootdep[var-1],rootdep[var],y,dpy+1);
            }
        }
    }
    
    //==================================================================
    int main()
    {
        int m,a,b,k,op;
        scanf("%d%d",&n,&m);
        build(1,n,rootfa[0]);
        for(int var=1;var<=m;var++)
        {
            scanf("%d",&op);
            if(op==1)
            {
                scanf("%d%d",&a,&b);
                merge(var,a,b);
            }
            else if(op==2)
            {
                scanf("%d",&k);
                rootfa[var]=rootfa[k];
                rootdep[var]=rootdep[k];
            }
            else 
            {
                scanf("%d%d",&a,&b);
                rootfa[var]=rootfa[var-1];
                rootdep[var]=rootdep[var-1];
                int x=find(var,a);
                int y=find(var,b);
                if(x==y) puts("1");
                else puts("0");
            }
        }
        return 0;
    }
  • 相关阅读:
    git 回滚merge的两个分支
    java 将一段时间分割为两个连续的时间
    Linux 命令记录
    C# WebBrowser 设置独立的代理
    VS2019 开发Django(八)------视图
    VS2019 开发Django(七)------VS2019不能格式化html代码
    VS2019 开发Django(六)------Admin中图片上传
    VS2019 开发Django(五)------createsuperuser
    VS2019 开发Django(四)------models
    VS2019 开发Django(三)------连接MySQL
  • 原文地址:https://www.cnblogs.com/YangKun-/p/12899808.html
Copyright © 2011-2022 走看看