假设有A,B,C,D,E,5个人A,B在一个朋友圈内,B,C在一个朋友圈内,这样A,B,C就在一个朋友圈内,总共有多少个朋友圈。
当人数较多时不容易算出。
可以利用数据结构查并集。
设5个人的初值为-1,用数组下标代替A,B,C,D,E
A,B在一个朋友圈,设A为根,B的值替换为A的下标,将A,B合并,A加上B本身的值为-2代表朋友圈内有两个人,当所取得值为负数时为根,为正数时代表所在朋友圈根的系数。
B,C在一个朋友圈,B的值为0不是负数,所以不是根,下标为0的数是-2,是根,将他们合并。
最后为负数的有三个A,D,E,因为B,C的值为0,所以B,C属于A朋友圈,所以总共有三个朋友圈ABC 和 D和E。
#include <iostream>
#include <vector>
using namespace std;
class UnionSet {
public:
UnionSet(size_t n)
:_ufs(n, -1)
{ }
int Getparent(size_t index)
{
int parent = index;
while (_ufs[parent] >= 0)
{
parent = _ufs[parent];
}
return parent;
}
bool IsUnion(size_t index1, size_t index2)
{
return Getparent(index1) == Getparent(index2);
}
void Union(size_t index1, size_t index2)
{
size_t root1 = Getparent(index1);
size_t root2 = Getparent(index2);
if (root1 != root2)
{
_ufs[root1] += _ufs[root2];
_ufs[root2] = root1;
}
}
size_t Size() //返回有多少个集合
{
size_t count = 0;
for (int i = 0; i < _ufs.size(); ++i)
{
if (_ufs[i] < 0)
count++;
}
return count;
}
private:
vector<int> _ufs;
};
int main()
{
UnionSet un(5);
un.Union(0, 1);
un.Union(1, 2);
cout << un.Size() << endl;
}