朋友圈的“真相”—并查集(UnionFindSet)
2017-05-21 20:43
169 查看
一道笔试题
已知有n个人,m对好友关系(存于数字r),若两个人是直接或间接的好友(好友的好友的好友……),则认为他们同属于一个朋友圈。例如:n = 5,m = 3,r={{1,2},{2,3},{4,5}};表示一共有5个人,3对好友关系,其中,1和2是好友,2和3是好友,4和5是好友;则1、2、3是一个朋友圈,4、5是一个朋友圈,结果是两个朋友圈。
问题:编写程序求出这n个人里有多少个朋友圈
对于这个问题,楼主刚开始是一脸懵逼的,但学了并查集之后,妈妈再也不用担心我不会啦^-^
并查集(UnionFindSet)
以上面这道题为基础,假设有这样一个数组,它由5个元素构成,初值全为-1上面的下标就表示5个人。
接下来,我们用树状图来表示好友之间的关系:
如果我们把好友关系用数组元素来表示,2是1的好友,就把2下标处的数据叠加到1处,2处的数据存放1下标;3是2的好友,但2是1的好友,所以把3下标处的数据也叠加到1处,3处的数据存放2下标。4,5同理。
上边的数组就会变为:
由此我们可以总结出以下几点:
1.只要某下标处的数据是负数,它就是其所在朋友圈的“根”。负数的大小代表着朋友圈的人数,如下标1出的数据是-3,就说明此朋友圈有3个人。
2. 数组中有几个负数就说明有几个朋友圈,如该数组有2个负数,所以有2个朋友圈。
3.由各下标对应的数据可以找到“根”,有相同根的下标就在一个朋友圈中,如2和3拥有相同的根1,所以它们是一个朋友圈中的。
我们把上边的朋友圈换成“集合”,人换成集合中的“元素”,就可以得到并查集(UnionFindSet)的概念:
并查集就是将N个不同的元素分成一组不相交的集合;开始时,每个元素就是一个集合,然后按规律将两个集合进行合并。
按上边的例子可以理解为:开始时,每个人就是一个朋友圈,然后按照好友关系将人与人之间关联合并起来,形成最终的朋友圈。
有了并查集的概念,这道笔试题就很容易解决了。我们只需要建立一个并查集,然后实现判断接口,就可以Get到朋友圈的个数了。
Code
#include<iostream> #include<Windows.h> class UnionFindSet { public: UnionFindSet(int n) :_set(new int ) { for (int i = 0; i <n; ++i) { _set[i] = -1; } } int FindRoot(int index) { int root = index; while (_set[root] > 0) { root = _set[root]; } return root; } void UnionPeople(int index1, int index2) { int root1 = FindRoot(index1-1); int root2 = FindRoot(index2-1); if (root1 != root2) { _set[root1] += _set[root2]; _set[root2] = root1; } } int CountCircleNumber(int n) { int count = 0; for (int i = 0; i < n; ++i) { if (_set[i] < 0) { count++; } } return count; } ~UnionFindSet() { if (_set ) { delete[] _set; } _set = NULL; } private: int *_set; }; int FriendCircle(int n, int m, int r[][2]) { UnionFindSet f(n); for (int i = 0; i < m; ++i) { f.UnionPeople(r[i][0], r[i][1]); } return f.CountCircleNumber(n); } int main() { //Test(); int r[][2] = { { 1, 2 }, { 2, 3 }, { 4, 5 } }; FriendCircle(5, 3, r); system("pause"); }
相关文章推荐
- 九度题目1526:朋友圈 小米2013年校园招聘笔试题 并查集
- 图—并查集(解决朋友圈问题)
- 并查集(朋友圈)
- 并查集解决朋友圈问题
- 朋友圈 - 图遍历 - 并查集
- 朋友圈问题(并查集)
- PAT 朋友圈(并查集)
- 并查集解决朋友圈问题
- 并查集朋友圈的范围
- 并查集-朋友圈
- 九度OJ 朋友圈 并查集
- 九度oj 1526 朋友圈 并查集
- 5-25 朋友圈 (25分) -- 简单并查集
- 小米面试题---朋友圈问题(并查集)
- 九度OJ题目 1526 朋友圈 并查集
- 九度OJ 朋友圈 -- 并查集
- PTA 5-16 朋友圈 (25分)【并查集】
- 并查集-UnionSet【朋友圈问题】
- 并查集(UnionFindSet)