C++並查集
阿新 • • 發佈:2022-03-27
#include<stdc++.h> #include <iostream> using namespace std; class ufset{ public: static const int N = 100010; int p[N]; // p[i]看做i的指標,該指標指向其父節點。 int cnt[N]; // cnt[i]看做i為root時候的樹節點總個數。 ufset(int size){ for(int i = 0; i < size; i++){ p[i] = i; // 每個i都是root cnt[i] = 1; // 每個i都是root,節點數為1 } } int find(int i){ //查詢roor if(p[i] != i){ // 如果當前節點不是root, p[i] = find(p[i]);//找到其父節點的root,當前節點指向其父節點的root } return p[i]; // 當前節點的父節點一定為集合的root } bool isUnion(int le, int ri){ // 兩個節點時候一個集合 return p[le] == p[ri]; //兩節點的root是否相同 } void unionD(int le, int ri){ // 合併兩個集合 cnt[find(le)] += cnt[find(ri)]; //兩集合節點數相加 p[find(ri)] = find(le);//右集合指向左集合的root } int cntI(int i){ // 計算當前集合數量 return cnt[find(i)];// 找到root,再找cnt[root] } }; int main(){ ufset us(10); us.unionD(1,2); us.unionD(3,2); us.unionD(4,5); us.unionD(6,5); us.unionD(7,9); cout << "find(): "; for(int i = 1; i < 10; i++){ cout << us.find(i) << ","; } cout << endl << "p[]: "; for(int i = 1;i < 10; i++){ cout << us.p[i] << ","; } cout << endl << "cnt[]: "; for(int i = 1;i < 10; i++){ cout << us.cnt[i] << ","; } us.unionD(1,9); // 兩個集合合併 cout << "兩個集合合併:us.unionD(1,9);" << endl; cout << endl << "p[]: "; for(int i = 1;i < 10; i++){ cout << us.p[i] << ","; } cout << endl << "cnt[]: "; for(int i = 1;i < 10; i++){ cout << us.cnt[i] << ","; } cout << endl << us.cntI(9); cout << endl << "p[]: "; for(int i = 1;i < 10; i++){ cout << us.p[i] << ","; } return 0; }