UnionFind/Windows_UnionFindSet/UnionFindSet.hpp

120 lines
2.8 KiB
C++
Raw Normal View History

#pragma once
#include <iostream>
#include <vector>
#include <map>
namespace Lenyiin
{
class UnionFindSet
{
public:
// <20><>ʼ<EFBFBD><CABC>: Ϊÿ<CEAA><C3BF>Ԫ<EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><>ʼʱÿ<CAB1><C3BF><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>СΪ 1, <20><> -1 <20><>ʾ
UnionFindSet(int n)
: _v(n, -1) // <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD>ض<EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD>ڵ<EFBFBD>, <20>Ҽ<EFBFBD><D2BC>ϴ<EFBFBD>СΪ1
{
}
// <20><><EFBFBD>Ҳ<EFBFBD><D2B2><EFBFBD>: <20>ҵ<EFBFBD>Ԫ<EFBFBD><D4AA> x <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵĸ<CFB5><C4B8>ڵ<EFBFBD>, <20><>ʹ<EFBFBD><CAB9>·<EFBFBD><C2B7>ѹ<EFBFBD><D1B9><EFBFBD>Ż<EFBFBD>
int FindRoot(int x)
{
int root = x;
// <20><><EFBFBD>Ҹ<EFBFBD><D2B8>ڵ<EFBFBD>, <20><><EFBFBD>Ÿ<EFBFBD><C5B8>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѱ<EFBFBD><D1B0>
while (_v[root] >= 0)
{
root = _v[root];
}
// ·<><C2B7>ѹ<EFBFBD><D1B9>: <20><>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>нڵ<D0BD>ֱ<EFBFBD>ӹ<EFBFBD><D3B9>ڸ<EFBFBD><DAB8>ڵ<EFBFBD><DAB5><EFBFBD>
while (x != root)
{
int parent = _v[x]; // <20><><EFBFBD>浱ǰ<E6B5B1>ڵ<EFBFBD><DAB5>ĸ<EFBFBD><C4B8>ڵ<EFBFBD>
_v[x] = root; // <20><><EFBFBD><EFBFBD>ǰ<EFBFBD>ڵ<EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD><D3B5><EFBFBD><EFBFBD>ڵ<EFBFBD>
x = parent; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>
}
return root; // <20><><EFBFBD>ظ<EFBFBD><D8B8>ڵ<EFBFBD>
}
// <20>ϲ<EFBFBD><CFB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: ʹ<>ð<EFBFBD><C3B0>Ⱥϲ<C8BA><CFB2>Ż<EFBFBD>
bool Union(int x1, int x2)
{
int root1 = FindRoot(x1);
int root2 = FindRoot(x2);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϲ<EFBFBD>
if (root1 == root2)
{
return false;
}
// <20><><EFBFBD>Ⱥϲ<C8BA>: ʼ<>ս<EFBFBD><D5BD><EFBFBD>С<EFBFBD>ļ<EFBFBD><C4BC>Ϲҵ<CFB9><D2B5>ϴ<EFBFBD><CFB4>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>
if (_v[root1] < _v[root2]) // root1 <20><><EFBFBD>Ϲ<EFBFBD>ģ<EFBFBD>ϴ󣨸<CFB4>ֵԽС, <20><><EFBFBD><EFBFBD>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD>
{
_v[root1] += _v[root2]; // <20><><EFBFBD><EFBFBD> root1 <20><><EFBFBD>ϵĴ<CFB5>С
_v[root2] = root1; // root2 <20>ҵ<EFBFBD> root1 <20><>
}
else
{
_v[root2] += _v[root1]; // <20><><EFBFBD><EFBFBD> root2 <20><><EFBFBD>ϵĴ<CFB5>С
_v[root1] = root2; // root1 <20>ҵ<EFBFBD> root2 <20><>
}
return true; // <20>ϲ<EFBFBD><CFB2>ɹ<EFBFBD>
}
// <20>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>ͬһ<CDAC><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool InSet(int x1, int x2)
{
return FindRoot(x2) == FindRoot(x2);
}
// ͳ<>Ƶ<EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD>ϵĸ<CFB5><C4B8><EFBFBD>
size_t SetSize()
{
size_t count = 0;
for (auto e : _v)
{
if (e < 0) // ֻ<>и<EFBFBD><D0B8>ڵ<EFBFBD><DAB5><EFBFBD><E6B4A2>ֵ, <20><>ʾ<EFBFBD><CABE><EFBFBD>ϵĴ<CFB5>С
{
++count;
}
}
return count;
}
// <20><>ӡ<EFBFBD><D3A1>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>Ľṹ (<28><><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>)
void Print() const
{
for (int i = 0; i < _v.size(); ++i)
{
printf("v[%d] == %d\n", i, _v[i]);
}
printf("\n");
}
private:
std::vector<int> _v; // <20>洢ÿ<E6B4A2><C3BF>Ԫ<EFBFBD>صĸ<D8B5><C4B8>ڵ<EFBFBD><DAB5>򼯺ϴ<F2BCAFBA>С
};
}
// namespace Lenyiin
//{
// template <class T>
// class UnionFindSet
// {
// public:
// UnionFindSet(const T* a, size_t n)
// {
// for (size_t i = 0; i < n; ++i)
// {
// _v.push_back(a[i]);
// _indexmap[a[i]] = i;
// }
// }
//
// private:
// vector<T> _v; // <20><><EFBFBD>ұ<EFBFBD><D2B1><EFBFBD>
// map<T, int> _indexmap; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// };
// }