首页 > 技术文章 > 【模板】并查集 两种路径压缩写法(类模板和函数模板)

zhangjiuding 2017-10-22 17:01 原文

 并查集函数模板写法:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define MAX_N 1000


int par[MAX_N]; //par[i]表示i节点的父节点 
int rank[MAX_N]; // 树的高度 

//初始化n个元素
void init(int n){
    for(int i = 0;i < n; i++){
        par[i] = i;
        rank[i] = 0;
    }
} 

//查询包含x节点的树的根 
int find(int x){
    if(par[x] == x) return x;
    else return par[x] = find(par[x]); 
}

//合并 x和y所属的集合 
void unite(int x,int y){
    x = find(x);
    y = find(y);
    if(x == y) return;
    
    if(rank[x] < rank[y]){
        par[x] = y; 
    }else{
        par[y] = x;
        if(rank[x] == rank[y]) rank[x]++;
    }
}

//判断x和y是否属于同一个集合 
bool same(int x,int y){
    return find(x) == find(y);
}

int main(){
    
    
    return 0;
} 

 

 

 并查集类模板写法:

class UnionFind{
private:
    int* parent;
    int* rank;
    int count;
public:
    UnionFind(int count){
        parent = new int[count];
        rank = new int[count];
        this->count = count;
        for(int i = 0;i < count; i++){
            parent[i] = i;
            rank[i] = 1;
        }
    }
    ~UnionFind(){
        delete[] parent;
        delete[] rank;
    }

    int find(int p){
        assert(p >= 0&&p < count);
 /*       while(parent[p] != p){
            parent[p] = parent[parent[p]];
            p = parent[p];
        }*/ // 实践更好
        if(p != parent[p])      //理论更好
            parent[p] = find(parent[p]);
        return parent[p];
    }

    bool isConnected(int p,int q){
        return find(p) == find(q);
    }

    void unionElements(int p,int q){
        int pRoot = find(p);
        int qRoot = find(q);
        if(pRoot == qRoot)
            return;


        if(rank[pRoot]  < rank[qRoot]){
            parent[pRoot] = qRoot;
        }else if(rank[pRoot] > rank[qRoot]){
            parent[qRoot] = pRoot;
        }else{
            parent[pRoot] = qRoot;
            rank[qRoot]++ ;
        }
    }
};

 

推荐阅读