并查集

不带权并查集

1、时间复杂度为 \(O(n)\)

struct DSU{
    int n, cnt;
    vector<int> fa, siz;
    DSU() {}
    DSU(int n_) : fa(n_ + 1), siz(n_ + 1, 1) {
        n = n_;
        cnt = n;
        iota(fa.begin(), fa.end(), 0);
    }
    
    inline void init() {
		
	}
    
    inline int find(int x) {
        return x == fa[x] ? x : fa[x] = find(fa[x]);
    }
    
    inline bool ral(int x, int y) {
        return find(x) == find(y);
    }
    
    inline bool mergy(int x, int y) {
        int fx = find(x);
        int fy = find(y);
        if (fx == fy) return false;
        
        if (siz[fx] > siz[fy]) swap(fx, fy);
        
        cnt--;
        fa[fx] = fy;
        siz[fy] += siz[fx];
        return true;
    }
};

带权并查集

1、时间复杂度为 \(O(n)\)

2、模版:洛谷P1196

struct DSU{
	int n, cnt;
	vector<int> fa, siz, d;// 数组d用了向量法则
	DSU() {}
	DSU(int n_) : fa(n_ + 1), siz(n_ + 1, 1), d(n_ + 1) {
        n = n_;
        cnt = n;
        iota(fa.begin(), fa.end(), 0);
    }
	
	inline void init() {
		
	}
	
	inline int find(int x) {
		if (x == fa[x]) return x;
		int f = fa[x];
		fa[x] = find(fa[x]);
		d[x] += d[f];
		return fa[x];
	}
	
	inline bool ral(int x, int y) {
		return find(x) == find(y);
	}
	
	inline bool mergy(int x, int y) {
		int fx = find(x);
		int fy = find(y);
		if (fx == fy) return false;
		
		cnt--;
		fa[fx] = fy;
		d[fx] += siz[fy];
		siz[fy] += siz[fx];
		return true;
	}
};

按秩排序

1、时间复杂度为 \(O(n)\),也可能稍微大一点 。

struct DSU{
    int n;
    vector<int> rk, fa;
	DSU() {}
    DSU(int n_) : rk(n_ + 1, 1), fa(n_ + 1) {
        n = n_;
        iota(fa.begin(), fa.end(), 0);
    }

    inline int find(int x) {
        return x == fa[x] ? x : fa[x] = find(fa[x]);
    }
    
    inline bool mergy(int x, int y) {
        int fx = fa[x];
        int fy = fa[y];

        if (fx == fy) {
            return false;
        }

        if (rk[fx] > rk[fy]) {
            swap(fx, fy);
        }
        
        fa[fx] = fy;
        if (rk[fx] == rk[fy]) {
            rk[fy]++;
        }
        return true;
    }
};

按秩排序

1、定义:可执行可撤销并查集操作,不过只能按照操作顺序进行撤销。

vector<PI> st;
struct DSU{
    int n;
    vector<int> rk, fa;
	DSU() {}
    DSU(int n_) : rk(n_ + 1, 1), fa(n_ + 1) {
        n = n_;
        iota(fa.begin(), fa.end(), 0);
    }

    inline int find(int x) {
        return x == fa[x] ? x : find(fa[x]);
    }
    
    inline bool mergy(int x, int y) {
        int fx = fa[x];
        int fy = fa[y];

        if (fx == fy) {
            return false;
        }

        if (rk[fx] > rk[fy]) {
            swap(fx, fy);
        }
        st.push_back({fx, rk[fx] == rk[fy]});
        fa[fx] = fy;
        if (rk[fx] == rk[fy]) {
            rk[fy]++;
        }
        return true;
    }
};

while (!st.empty()) {
	
}
posted @ 2024-08-12 20:22  grape_king  阅读(38)  评论(1)    收藏  举报