zoukankan      html  css  js  c++  java
  • 并查集

    概念:

    初始状态所有点自成一个集合

    包括两个基本操作:

    1.把两个集合合并成一个大集合

    2.查询点x和y是否属于同一个集合

    优化:

    按秩合并:

    维护树的深度size,把深度小树的当儿子,将其根节点作为深度较大的树的树根的子节点合并

    时间复杂度O(logn)

    路径压缩:

    找到x的根节点后,把路径上所有的节点都直接接到根节点上

    时间复杂度O(logn)

    code:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define maxn 100010
    using namespace std;
    struct bcj{
        int fa[maxn];
        int size[maxn];
        void init(int n){
            for(int i=1;i<=n;i++) fa[i]=i;
            for(int i=1;i<=n;i++) size[i]=1;
        }
        int f(int x){
            return fa[x]=(fa[x]==x)?x:f(fa[x]);//"fa[x]="为路径压缩,把x直接连到根节点上 
        }
        void u(int x,int y){
            x=f(x);y=f(y);
            if(x==y) return ;//return一定要紧跟着上一行写,防止加其他东西的时候出现非法操作 
            if(size[x]>size[y]) swap(x,y);
            size[y]+=size[x];        
            fa[x]=y;//这3行代码为按秩合并,把小的树接到大的树上 
        }
    }s;
    
    int main(){
        int n,m;
        cin>>n>>m;
        s.init(n);
        for(int i=1;i<=m;i++){
            int x,y,z;
            cin>>z>>x>>y;
            if(z==1) s.u(x,y);
            else cout<<((s.f(x)==s.f(y))?"Y":"N")<<endl;
        }
        return 0;
    }

    题目传送门:洛谷P3367

  • 相关阅读:
    HDU 1564 Play a game(巴什博弈)
    威佐夫博弈(Wythoff Game)
    产生冠军 hdoj_2094 巧用set
    find your present (感叹一下位运算的神奇)
    快速排序
    深度优先搜索(DFS)
    hdoj 2075 A|B?
    基础练习 特殊回文数
    10.Nginx Rewrite重写
    07.Nginx七层负载均衡
  • 原文地址:https://www.cnblogs.com/DReamLion/p/14384912.html
Copyright © 2011-2022 走看看