1.基本知识概念

等价类与并查集。如果用符号“=”表示集合上的等价关系,那么对于该集合中的任意对象x,y,z,下列性质成立 :
自反性:x=x(即等于自身)
对称性:若x=y,则y=x
传递性:若x=y且y=z,则x=z
一个集合S中的所有对象可以通过等价关系划分为若干个互不相交的子集S1,S2,S3,…,它们的并集就是S,这些子集即为等价类。
确定等价类的方法:
第一步:读入并储存所有的等价对(i,j);
第二步:标记和输出所有的等价类。

2.解决步骤分析:

假定给定集合:S={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
及以下等价对:
①0=4
②3=1
③6=10
④8=9
⑤7=4
⑥6=8
⑦3=5
⑧2=11
⑨11=0
我们以等式左边的值为根,最后一棵树是一个等价类,如果两个结点的根节点相同,就是在一个等价类。
如下解决过程:

如下图,黑色的为单个等价类,其他颜色相同的为一个等价类,我们以等号左边的作为根:

处理完⑤-⑧后的结果 :

处理完⑨后的结果 :

3.解决代码:

3.1正常普通解决代码:

class UFsets
{private:int* parent;unsigned int size;
public:UFsets(unsigned int sz){size = sz;parent = (int*)malloc(sizeof(int) * sz);for (int i = 0; i < size; i++){parent[i] = -1;}}~UFsets(){free(parent);}bool Union(int a, int b){bool res = false;int ra = FindParent(a);int rb = FindParent(b);if (ra != rb){parent[ra] += parent[rb];parent[rb] = ra;res = true;}return res;}int FindParent(int ra){while (parent[ra] >= 0){ra = parent[ra];}return ra;}void Print(int ri){printf("%3d ", ri);for (int i = 0; i < size; i++){if (parent[i] == ri){Print(i);}}}void PrintSet(){int s = 0;for (int i = 0; i < size; i++){if (parent[i] < 0){printf("第 %d 集合\n", ++s);Print(i);printf("\n");}}}
};int main()
{UFsets set(12);set.Union(0, 4);set.Union(3, 1);set.Union(6, 10);set.Union(8, 9);set.Union(7, 4);set.Union(6, 8);set.Union(3, 5);set.Union(2, 11);set.Union(11, 0);return 0;
}

调试查看parent值发现和我们分析时最后的数组结果一样(我统一以等价左边的值作为根):

用类的PrintSet()打印各个等价类结果:

4.加权规则和折叠规则

但是Find和Union的操作性能不好。假设最初n个元素构成n棵树组成的森林,parent[i] = -1。做处理Union(n-2,n-1),Union(n-3,n-1),Union(n-4,n-1)…Union(0,n-1)后,将产生如下图所示的退化的树:

执行一次Union操作需时间O(1),n-1此是O(n)。若再执行Find(0),Find(1),…,Find(n-1),若被搜索的元素为i,完成Find(i)操作为O(i),完成n次搜索是O(n^2)。
所以在这里提出了加权规则和折叠规则。

4.1加权规则

先判断两个集合中的结点个数,如果以i为根的树中的结点个数少于以j为根的树中的结点个数,即parent[i] > parent[j],则让j成为i的双亲,否则,让i成为j的双亲。以下即为加权规则代码吗,将以下代码添加到class UFsets中即可。

bool WeightedUnion(int a, int b)//加权规则{bool res = false;int ra = FindParent(a);int rb = FindParent(b);if (ra != rb){if (parent[ra] > parent[rb])//说明parent[rb]结点更多,让rb成为根节点{parent[rb] += parent[ra];parent[ra] = rb;}else//让ra成为根节点{parent[ra] += parent[rb];parent[rb] = ra;}res = true;}return res;}

4.2折叠规则

如果j是从i到根的路径上的一个结点,并且parent[j] ≠ root,则把parent[i]置于root,意思是让i的双亲直接为root。
如下即为从i结点向上压缩路径,将代码添加到class UFsets中即可 :

//折叠规则压缩路径void Coollapsingfind(int i){int j = i;while (parent[j] >= 0)//寻找树的根节点{j = parent[j];}while (i != j){int tmp = parent[i];parent[i] = j;i = tmp;}}

以下为折叠压缩后的结果:

并查集(加权规则、折叠规则)相关推荐

  1. Rochambeau POJ - 2912 (枚举和加权并查集+路径压缩)找唯一裁判

    题意:有n个人玩石头剪刀布,有且只有一个裁判.除了裁判每个人的出拳形式都是一样的. a<b表示b打败a,a=b表示a和b出拳一样,平手.a>b表示a打败b. 给出m个回合的游戏结果,问能否 ...

  2. hdu 3635 Dragon Balls(加权并查集)2010 ACM-ICPC Multi-University Training Contest(19)

    这道题说,在很久很久以前,有一个故事.故事的名字叫龙珠.后来,龙珠不知道出了什么问题,从7个变成了n个. 在悟空所在的国家里有n个城市,每个城市有1个龙珠,第i个城市有第i个龙珠. 然后,每经过一段时 ...

  3. 拼多多关键词的排名是怎么查?拼多多排名规则

    拼多多产品的标题,关键词非常重要,现在企业需要每天找到好的关键词或比较同行关键词,知道一般排名,大类别和小类别关键词不同,客户搜索商品关键词惯性,是企业需要了解,好的关键词可以给商店带来好的流量,所以 ...

  4. 快手集福气中国牛 2021快手集福卡活动规则

    快手集福气中国牛,集福卡活动规则 一.活动时间 2021年1月29日00:00 至2021年2月10日23:59 二.活动玩法 1.福卡介绍 福卡分为两种,即福气卡与福牛卡,每种卡均有五种字符卡片如下 ...

  5. A Bug‘s Life POJ 2492 加权并查集

    A Bug's Life POJ 2492 加权并查集 传送门:http://poj.org/problem?id=2492 Description Background Professor Hopp ...

  6. poj1182(加权值的并查集)

    Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A.  现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它 ...

  7. 【加权并查集】bzoj 4602 齿轮

    立志用最少的代码做最高效的表达 Description 现有一个传动系统,包含了N个组合齿轮和M个链条.每一个链条连接了两个组合齿轮u和v,并提供了一个传动比x : y.即如果只考虑这两个组合齿轮,编 ...

  8. Zjnu Stadium HDU - 304 加权并查集

    题意: 观众席围成一圈.列的总数是300,编号为1–300,顺时针计数,我们假设行的数量是无限的.将有N个人去那里.他对这些座位提出了要求:这意味着编号A的顺时针X距离坐着编号B.例如:A在第4列,X ...

  9. 数据结构 之 并查集

    并查集是一种树型的数据结构,其保持着用于处理一些不相交集合(Disjoint Sets)的合并及查询问题. 有一个联合-查找算法(union-find algorithm)定义了两个操作用于此数据结构 ...

最新文章

  1. 炸裂!MySQL 82 张图带你飞!
  2. TeskLink—增加一种需求类型(业务流程)(version1.9.8)
  3. Google App Engine技术架构之Google App Engine的简介
  4. android base64解密,android Base64 AES加密解密
  5. [move_base-24] process has died [exit code -6, cmd lib/move_base/move_base odom:=mobile_base_control
  6. httpclient 学习
  7. MyEclipse2015修改项目部署名称(WebContextRoot)
  8. 一、Web服务器——Tomcat Servlet学习笔记
  9. 如何查看mysql8.0的默认密码_MySQL8.0安装之后查找默认密码
  10. IndexError:boolean index did not match indexed array along dimension 0
  11. python123用户登录的三次机会_用户登录三次机会(PYTHON)
  12. 2021-02-23 天地图图层类型总结
  13. 如何才能让项目团队高效稳定?
  14. java 字符串去重排序
  15. 解决 macOS Big Sur 新安装ideaIU-2021.2.2 无法启动
  16. webpack 代码压缩优化篇
  17. li序号 ul_ul ol li的序号编号样式
  18. ps怎样查看图片坐标
  19. 大众点评评论抓取-CSS加密破解
  20. Spring 4 - AOP

热门文章

  1. windows残留软件卸载
  2. kali2020提高权限到root
  3. iOS之深入解析如何检测“循环引用”
  4. 编写你的第一个 Django 应用,第 3 部分
  5. 4.Vue 模板语法
  6. Curses 中的 noecho() 函数
  7. Linux基础 —— Linux终端命令格式
  8. ubuntu下超级用户和普通用户
  9. LeetCode 287. Find the Duplicate Number (时间复杂度O(n)) + 链表判断环
  10. Codeforces 991E. Bus Number (DFS+排列组合)