假如已知有n个人和m对好友关系(存于数字r)。如果两个人是直接或间接的好友(好友的好友的好友...),则认为他们属于同一个朋友圈,请写程序求出这n个人里一共有多少个朋友圈。假如:n = 5 , m = 3 , r = { { 1, 2 }, { 2, 3 }, { 4, 5 } },表示有5个人,1和2是好友,2和3是好友,4和5是好友,则1、2、3属于一个朋友圈,4、5属于另一个朋友圈,结果为2个朋友圈。最后请分析所写代码的时间、空间复杂度。评分会参考代码的正确性和效率。
#include<iostream>
using namespace std;
#include<assert.h>
class UnionFindSet
{
typedef UnionFindSet YC;
public:
YC(int N)
: _sets(new int[N])
, _N(N)
{
memset(_sets, -1, sizeof(int)*N);
}
int FindRoot(int x)
{
while (_sets[x] >= 0)
{
x = _sets[x];
}
return x;
}
void Union(int x1, int x2)
{
int root1 = FindRoot(x1);
int root2 = FindRoot(x2);
if (root1 != root2)
{
_sets[root1] += _sets[root2];
_sets[root2] = root1;
}
}
int Count()
{
int k = 0;
for (int i = 0; i < _N; ++i)
{
if (_sets[i] < 0)
{
k++;
}
}
return k;
}
protected:
int *_sets;
int _N;
};
int friends(int n, int m, int r[][2])
{
assert(r);
UnionFindSet ufs(n + 1);
for (int i = 0; i < m; ++i)
{
int r1 = r[i][0];
int r2 = r[i][1];
ufs.Union(r1, r2);
}
return ufs.Count() - 1;
}
int main()
{
int r[][2] = { { 1, 2 }, { 2, 3 }, { 4, 5 } };
int ret = friends(5, 3, r);
printf("ret=%d\n", ret);
system("pause");
return 0;
}