120 lines
2.8 KiB
C++
120 lines
2.8 KiB
C++
|
#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>
|
|||
|
// };
|
|||
|
// }
|