小米的一道面试题:
假如已知有n个人和m对好友关系,如果两个人是直接或者间接有好友关系,则认为他们属于同一个朋友圈。写程序判断里面有多少朋友圈。
例如:
n = 5, m = 3 r = {(1,2), (2, 3), (4, 5)} 1 2 3 是一个朋友圈, 4 5 是一个朋友圈。
所以输出是2
这道题用并查集来求解就非常容易了。关于并查集的内容,这篇文章写得非常好:
http://blog.csdn.net/dm_vincent/article/details/7655764#reply
根据这篇文章,写了一个求解方法,代码如下:
- class UnionFind {
- public:
- UnionFind(int n) : cnt(n)
- {
- id = new int[n];
- for (int i = 0; i < n; i++)
- id[i] = i;
-
- size = new int[n];
- for (int i = 0; i < n; i++)
- size[i] = 1;
- }
-
- ~UnionFind()
- {
- delete[] id;
- delete[] size;
- }
-
-
- int count()
- {
- return cnt;
- }
-
-
- int findSet(int a)
- {
- if (id[a] == a)
- return a;
- else
- return id[a] = findSet(id[a]);
- }
-
- bool isSameSet(int a, int b)
- {
- int x = findSet(a);
- int y = findSet(b);
-
- return x == y;
- }
-
- void Union(int a, int b)
- {
- int x = findSet(a);
- int y = findSet(b);
-
- if (x != y)
- {
- if (size[x] < size[y])
- {
- id[x] = y;
- size[y] += size[x];
- }
- else
- {
- id[y] = x;
- size[x] += size[y];
- }
-
- cnt--;
- }
- }
-
- private:
- int *id;
- int *size;
- int cnt;
- };
-
- int main()
- {
- UnionFind friends(5);
-
- friends.Union(0, 1);
- friends.Union(1, 2);
- friends.Union(3, 4);
-
- cout << "朋友圈数目:" << friends.count() << endl;
-
- system("pause");
- return 0;
- }
运行结果: