muse网站设计解决方案视频教程,免费域名申请网站大全下载,在线crm什么软件好,做网站需要的执照1、并查集原理 在一些应用问题中#xff0c;需要将n个不同的元素划分成一些不相交的集合#xff1b;开始时#xff0c;每个元素自成一个 单元素集合#xff0c;然后按一定的规律将归于同一组元素的集合合并#xff1b;在此过程中要反复用到查询某一 个元素归属于那个集合的…1、并查集原理 在一些应用问题中需要将n个不同的元素划分成一些不相交的集合开始时每个元素自成一个 单元素集合然后按一定的规律将归于同一组元素的集合合并在此过程中要反复用到查询某一 个元素归属于那个集合的运算适合于描述这类问题的抽象数据类型称为并查集(union-find set) 比如某公司今年校招全国总共招生10人西安招4人成都招3人武汉招3人10个人来自不 同的学校起先互不相识每个学生都是一个独立的小团体现给这些学生进行编号{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 给以下数组用来存储该小集体数组中的数字代表该小集体中具有成员的个 数。(负号下文解释) 毕业后学生们要去公司上班每个地方的学生自发组织成小分队一起上路于是 西安学生小分队s1{0,6,7,8}成都学生小分队s2{1,4,9}武汉学生小分队s3{2,3,5}就相互认识 了10个人形成了三个小团体。假设右三个群主0,1,2担任队长负责大家的出行 一趟火车之旅后每个小分队成员就互相熟悉称为了一个朋友圈 从上图可以看出编号6,7,8同学属于0号小分队该小分队中有4人(包含队长0)编号为4和9的同 学属于1号小分队该小分队有3人(包含队长1)编号为3和5的同学属于2号小分队该小分队有3 个人(包含队长1)
仔细观察数组中内融化可以得出以下结论
数组的下标对应集合中元素的编号数组中如果为负数负号代表根数字代表该集合中元素个数数组中如果为非负数代表该元素双亲在数组中的下标
在公司工作一段时间后西安小分队中8号同学与成都小分队1号同学奇迹般的走到了一起两个 小圈子的学生相互介绍最后成为了一个小圈子 现在0集合有7个人2集合有3个人总共两个朋友圈 通过以上例子可知并查集一般可以解决一下问题 1. 查找元素属于哪个集合 沿着数组表示树形关系以上一直找到根(即树中中元素为负数的位置) 2. 查看两个元素是否属于同一个集合 沿着数组表示的树形关系往上一直找到树的根如果根相同表明在同一个集合否则不在 3. 将两个集合归并成一个集合
将两个集合中的元素合并将一个集合名称改成另一个集合的名称 4. 集合的个数 遍历数组数组中元素为负数的个数即为集合的个数 2、并查集实现
class UnionFindSet
{
public:// 初始时将数组中元素全部设置为1UnionFindSet(size_t size): _ufs(size, -1){}// 给一个元素的编号找到该元素所在集合的名称int FindRoot(int index){// 如果数组中存储的是负数找到否则一直继续while(_ufs[index] 0){index _ufs[index];}return index;}bool Union(int x1, int x2){int root1 FindRoot(x1);int root2 FindRoot(x2);// x1已经与x2在同一个集合if(root1 root2)return false;// 将两个集合中元素合并_ufs[root1] _ufs[root2];// 将其中一个集合名称改变成另外一个_ufs[root2] root1;return true;}// 数组中负数的个数即为集合的个数size_t Count()const{size_t count 0;for(auto e : _ufs){if(e 0)count;}return count;}private:vectorint _ufs;
};3、并查集应用
省份数量等式方程的可满足性