17_08_并查集

并查集

  处理不相交集合的合并问题。

初始化:

int f[maxn];      //父亲数组,记录节点的父节点位置

void init(int n){                 //将每个节点的父节点初始化为它本身
    for(int i=0;i<n;i++){
        f[i]=i;
    }
}

查询根节点:

int find(int x){       //每次查询都要向上查询到根节点 ,坏情况下复杂度高
    return f[x]==x?x:find(f[x]);
}    

路径压缩优化:(一旦查询到一次根节点,就将根节点作为父节点

int find(int x){
    return f[x]==x?x:f[x]=find(f[x]);
}

判断是否属于同一个集合:

bool same(int x,int y){
    return find(x)==find(y);
}

合并:

void uni(int x,int y){
    int fx=find(x);
    int fy=find(y);
    if(fx!=xy)
    f[fy]=fx;
}

按秩合并:

void uni(int x,int y){
    int fx=find(x);
    int fy=find(y);
    if(fx==fy) return;
    if(rank[fx]<rank[fy]) f[fx]=fy;
    else{
        f[fy]=fx;
        if(rank[fx]==rank[fy])
            rank[fx]++;
    }
}//rank小的向rank大的连边,使树的高度尽量小
原文地址:https://www.cnblogs.com/anonym/p/8371727.html