并查集
2016-07-15 22:14
288 查看
题目:n个人有m对好友关系,如果俩个人是直接或者间接的好友(好友的好友的好友...),则认为他们是同一个朋友圈。请问这n个人里一共有多少个朋友圈
并查集的定义:1.将N个不同的元素分成一组不相交的集合。
2.开始时,每个元素就是一个集合,然后按规律将两个集合进行合并;
3.并查集的底层数据结构是数组。
例如:n=5,m=3,r = {{1,2},{2,3},{4,5}};有5个人,1,2是好友,2,3是好友,4,5是好友,1,2,3是一个朋友圈,4,5是一个朋友圈。结果为俩个朋友圈。
代码如下所示:
<span style="font-size:18px;">#pragma once class UnionSearchSet { public: //构造函数,开辟空间并去设置每个元素的值 UnionSearchSet(int size) :_size(size) { set = new int[_size]; for (int i = 0; i < _size; ++i) { set[i] = -1; } } //查找集合中其中一个数的root int Find(int root) { while (set[root] >= 0) { root = set[root]; } return root; } //先找到俩个集合的root,如果不一致则将root1合并到root2,并修改root2的root void Union(int x1, int x2) { int root1 = Find(x1); int root2 = Find(x2); if (root1 != root2) { set[root1] += set[root2]; set[root2] = root1; } } //计算有几个朋友圈:负数的个数(root),0不计算在内 int CountFriendCircle() { int count = 0; int i = 1; while (i < _size) { if (set[i] < 0) { ++count; } ++i; } return count; } private: int* set; int _size; }; //参数n:人数;参数m:几个集合; //根据给出的集合和实现的并查集结构判断有几个朋友圈 int Friends(int n, int m, int arr[][2]) { //传参时要多开辟一个人的空间,注意下标0不使用 UnionSearchSet fs(n + 1); int x1 = 0; int x2 = 0; for (int i = 0; i < m; ++i) { //一个集合一个集合去合并 x1 = arr[i][0]; x2 = arr[i][1]; fs.Union(x1, x2); } return fs.CountFriendCircle(); } //测试朋友圈问题 void TestFriendCircle() { int arr[][2] = { { 1, 2 }, { 2, 3 }, { 4, 5 } }; cout <<"朋友圈有"<< Friends(5, 3, arr)<<"个!"<<endl; int arr1[][2] = { { 1, 2 }, { 2, 3 }, { 3, 4 }, { 4, 5 }, { 6, 7 }, { 8, 9 } }; cout << "朋友圈有" << Friends(9, 6, arr1) << "个!" << endl; }</span>
测试结果如下图所示:
相关文章推荐
- Java Web实战08-Spring、Spring MVC和Hibernate实现收银机系统(XML版本)
- linux下的free命令和top命令
- UVA 1218 Perfect Service
- STM32学习笔记之点亮LED灯
- C++ - 二分查找完整版(包括注意细节)
- pandas module 1 - cookbook
- hdu 5285(染色法判断二分图)
- Mac搭建nginx+rtmp服务器
- 网络基本功(二):细说交换机
- 关于TSVM的一些学习资料
- SQL Server 2014 SP2
- Android仿微信SlideView聊天列表滑动删除效果
- ACM天梯赛 L3-003. 社交集群 (并查集)
- XML解析和序列化
- switch语句
- Tomcat9源码编译及导入Eclipse
- 猪数
- 【OpenCV笔记 08】OpenCV中分离颜色通道split()和图像通道混合merge()
- STM32学习笔记之外部中断实验
- HDU 2824 The Euler function