之前我已经写过一期的并查集的内容,这里主要是实现并查集的整体结构:
#pragma once
//并查集:
class UnionFindSet//父母表示法;
{
public:
//构造函数:
UnionFindSet(size_t size=0)
:_ufs(size,-1)
{}
//合并元素;
bool Union(int x, int y)
{
//找到两组元素的root
int root1 = FindRoot(x);
int root2 = FindRoot(y);
//检查:
//1.如果两组的root相同,返回false
//2.如果两组的root不同,合并,返回true
if (root1 == root2)
{
return false;
}
else
{
_ufs[root1] += _ufs[root2];
_ufs[root2] = root1;
//这里也可以通过压缩路径的方式,简化
return true;
}
}
bool UnionSize(int x, int y)
{
int root1 = FindRoot(x);
int root2 = FindRoot(y);
if (x == y)
{
return false;
}
else
{
//按照size合并,数量少的的合并数量多的
int size1 = SizeRoot(root1);
int size2 = SizeRoot(root2);
if (size1 < size2)
{
swap(root1, root2);
}
_ufs[root1] += _ufs[root2];
_ufs[root2] = root1;
return true;
}
}
//查找一个合并集合的root:
//非递归写法:
int FindRoot(int x)
{
//查找root(<0)
while (_ufs[x] > 0)
{
x = _ufs[x];
}
return _ufs[x];
}
//递归写法:
/*int FindRoot(int x)
{
if (x == _ufs[x])
return x;
else
return FindRoot(_ufs[x]);
}*/
//树的个数:
size_t Count()const
{
size_t count = 0;
for (auto e : _ufs)
{
count += (e < 0 ? 1 : 0);
}
return count;
//return x == fa[x] ? x : (fa[x] == findset2(fa[x]));//简写
}
//路径压缩:
//递归版;
int Path_compression(int x)
{
if (x == _ufs[x])
return x;
_ufs[x] = Path_compression(_ufs[x]);
return _ufs[x];
}
//非递归版;
/*int Path_compression(int x)
{
int root = FindRoot(root);
while(_ufs[x] != root)
{
int y = _ufs[x];
_ufs[x] = root;
x = y;
}
return root;
}*/
//一个树的元素个数:
int SizeRoot(int x)
{
int root = FindRoot(x);
return abs(_ufs[root]);
}
private:
vector<int> _ufs;
};
最后,祝福大家学习进步!!!