#include<iostream>
#include<windows.h>
#include<cassert>
//并查集 (连接问题,集合类的问题)
//union(p,q) find(p) isconnected
using namespace std;
class UnionFind1
{
private:
int *id;
int count;
public:
UnionFind1(int n){
count = n;
id = new int[n];
for(int i=0;i<n;i++){
id[i] = i;
//初始情况使每个ID等于各自ID
}
}
~UnionFind1(){
delete []id;
}
int find(int p){
assert(p>=0&&p<count);
return id[p];
}
bool isConnected(int p,int q){
return find(p)==find(q);
}
void unionElements(int p,int q){
//p q 组中所有数据连接
int pid = find(p);
int qid = find(q);
if(pid==qid)
return;
for(int i=0;i<count;i++){
if(id[i]==pid)
id[i]==qid;
}
}
};
class UnionFind2
{
private:
int *parent;
//数组元素指向自己的父亲
int count;
public:
UnionFind2(int n){
count = n;
parent = new int[n];
for(int i=0;i<n;i++){
parent[i] = i;
//初始情况使每个ID等于各自ID
}
}
~UnionFind2(){
delete []parent;
}
int find(int p){
assert(p>=0&&p<count);
while(p!=parent[p]){
p = parent[p];
}
return p;
}
bool isConnected(int p,int q){
return find(p)==find(q);
}
void unionElements(int p,int q){
//p q 组中所有数据连接
int pRoot = find(p);
int qRoot = find(q);
if(pRoot == qRoot)
return;
parent[pRoot] = qRoot;
}
};
class UnionFind3
{
private:
int *parent;
//数组元素指向自己的父亲
int *psize; //size[i]表示以i为根的集合中的元素
int count;
public:
UnionFind3(int n){
count = n;
parent = new int[n];
psize = new int[n];
for(int i=0;i<n;i++){
parent[i] = i;
psize[i] = 1;
//初始情况使每个ID等于各自ID
}
}
~UnionFind3(){
delete []parent;
delete []psize;
}
int find(int p){
assert(p>=0&&p<count);
while(p!=parent[p]){
p = parent[p];
}
return p;
}
bool isConnected(int p,int q){
return find(p)==find(q);
}
void unionElements(int p,int q){
//p q 组中所有数据连接
int pRoot = find(p);
int qRoot = find(q);
if(pRoot == qRoot)
return;
if(psize[pRoot]<psize[qRoot]){
parent[pRoot] = qRoot;
psize[qRoot] += psize[pRoot];
}
else{
parent[qRoot] = pRoot;
psize[pRoot] += psize[qRoot];
}
}
};
class UnionFind4
{
private:
int *parent;
//数组元素指向自己的父亲
int *rank; //rank[i]表示以i为根树的高度
int count;
public:
UnionFind4(int n){
count = n;
parent = new int[n];
rank = new int[n];
for(int i=0;i<n;i++){
parent[i] = i;
rank[i] = 1;
//初始情况使每个ID等于各自ID
}
}
~UnionFind4(){
delete []parent;
delete []rank;
}
int find(int p){
assert(p>=0&&p<count);
while(p!=parent[p]){
p = parent[p];
}
return p;
}
bool isConnected(int p,int q){
return find(p)==find(q);
}
void unionElements(int p,int q){
//p q 组中所有数据连接
int pRoot = find(p);
int qRoot = find(q);
if(pRoot == qRoot)
return;
if(rank[pRoot]<rank[qRoot]){
parent[pRoot] = qRoot;
//因为proot层数 <= qroot层数
}
else if(rank[qRoot]<rank[pRoot]){
parent[qRoot] = pRoot;
}
else{//rank[qRoot]==rank[pRoot]
parent[qRoot] = pRoot;
rank[qRoot] += 1;
}
}
};
//Path Compression路径压缩
//对find优化
class UnionFind5
{
private:
int *parent;
//数组元素指向自己的父亲
int *rank; //rank[i]表示以i为根树的高度
int count;
public:
UnionFind5(int n){
count = n;
parent = new int[n];
rank = new int[n];
for(int i=0;i<n;i++){
parent[i] = i;
rank[i] = 1;
//初始情况使每个ID等于各自ID
}
}
~UnionFind5(){
delete []parent;
delete []rank;
}
int findS(int p){
assert(p>=0&&p<count);
while(p!=parent[p]){
parent[p] = parent[parent[p]];
p = parent[p];
}
return p;
}
int findS_digui(int p){
assert(p>=0&&p<count);
if(p!=parent[p])
parent[p] = findS_digui(parent[p]);
return parent[p];
}
bool isConnected(int p,int q){
return findS(p)==findS(q);
}
void unionElements(int p,int q){
//p q 组中所有数据连接
int pRoot = findS(p);
int qRoot = findS(q);
if(pRoot == qRoot)
return;
if(rank[pRoot]<rank[qRoot]){
parent[pRoot] = qRoot;
//因为proot层数 <= qroot层数
}
else if(rank[qRoot]<rank[pRoot]){
parent[qRoot] = pRoot;
}
else{//rank[qRoot]==rank[pRoot]
parent[qRoot] = pRoot;
rank[qRoot] += 1;
}
}
};
int main(){
system("pause");
}
并查集----------模板(C++实现)
最新推荐文章于 2024-03-26 20:11:50 发布