假如已知有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;
}