详解并查集

详解并查集

                          Powered by WSY in SSF

                                   2019-11-02  13:46

【1】并查集的定义:

  并查集(Disjoint  Set)是一种非常精巧的非常实用的数据结构,它主要用来处理一些不相交集合的合并问题,经典的例子有联通子图,最小生成树的克鲁斯-卡尔算法。



【2】并查集的经典问题:

  我们通常使用“帮派”、“团伙”等问题举例说明并查集。例如帮派问题:

在某城市里住着n个人,任何两个认识的人不是朋友就是敌人,而且满足: 1、 我朋友的朋友是我的朋友; 2、 我敌人的敌人是我的朋友; 所有是朋友的人组成一个团伙。告诉你关于这n个人的m条信息,即某两个人是朋友,或者某两个人是敌人,请你编写一个程序,计算出这个城市最多可能有多少个团伙?

这是一个非常经典的并查集问题,接下来就用这个问题的代码为您详解并查集。



【3】并查集问题的基本思路:

  第一步   初始化:

  我们需要对存储公共祖先的数组进行初始化,一般情况下,将该数组命名为S。

首先,我们说 s[i] 是以节点 为元素的独立集合,在开始的时候不处理他和它的朋友之间的关系。

然后,以元素的值表示他的集 s[i] 的值,例如 元素1的集 s[1]=1,如图1.1所示。

第二步   计算+合并:

  合并,例如加入第1个朋友关系(1,2),如图1.2所示,在并查集S中,把节点1合并到节点2。

之后,以此类推,直到合并成如图1.3的样子。



  代码君:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int MAXN=1000+50;
 4 int R[MAXN],enemry[MAXN];
 5 int Find(int x)
 6 {
 7     return (!R[x])?x:(Find(R[x]));
 8 }
 9 void Union(int a, int b)
10 {
11     a=Find(a);
12     b=Find(b);
13     if(a==b) return;
14     if(a!=b) R[b]=a;
15 }
16 int main()
17 {
18     memset(R,0,sizeof(R));
19     memset(enemry,0,sizeof(enemry));
20     int m,n,x,y,j;
21     int ans=0;
22     char ch;
23     cin>>n>>m;
24     for(int i=0;i<m;i++)
25     {
26         cin>>ch>>x>>y;
27         if(ch==‘0‘)
28         {
29             if(enemry[x]) Union(y,enemry[x]);
30             else enemry[x]=y;
31             if(enemry[y]) Union(x,enemry[y]);
32             else enemry[y]=x;
33         }
34         else Union(x,y);
35     }
36     for(int i=1;i<=n;i++)
37     {
38         j=Find(i);
39         if(j==i) ans++;
40     }
41     cout<<ans<<endl;
42     return 0;
43 }//代码来源:https://blog.csdn.net/hyqsblog/article/details/45057877


【4】代码解读+详解

  再次感谢  https://blog.csdn.net/hyqsblog/article/details/45057877  提供的代码。

从主函数开始。

第18-19行,第1部分,初始化

  初始化R数组,enemry数组(这里很重要,在某些涉及到多组数据的题目时,初始化如果不写,会酿成大错)

第20-23行,第2部分,基础定义+输入

  这里定义了一些基本的,后面需要使用的变量。

之后还有一些基础的输入,包括N和M。

第24-35行,第3部分,循环查找,实现并查集中的 “合并”

  循环,循环每组关系,查找。

Line 27:如果这组关系是 “敌对”,那么就使用Union函数实现 “敌对合并” 的操作

Line 34:如果这组关系是 “友好”,那么就使用Union函数实现 “友好合并” 的操作

第9-15行,第4部分,实现合并

  使用Find函数实现查找合并

第5-8行,第5部分,实现查找

  全文只有一句话,但是能实现具体的返回判断,使用二次元运算符



【5】并查集题目推荐:

POJ2524 并查集简单题 Ubiquitous Religions
POJ1611 并查集简单题 The Suspects
POJ1703 并查集简单题 Find them, Catch them
POJ2236 并查集简单题 Wireless Network
POJ2492 并查集中等题 A Bug‘s Life
HDU3635 并查集中等题 Dragon Balls
HDU1856 并查集难题 More is Better
HDU1198 并查集传奇 Farm Irrigation

原文地址:https://www.cnblogs.com/Monach/p/11782264.html

时间: 2024-10-10 05:38:13

详解并查集的相关文章

详解MongoDB复制集(主从复制)

简介 复制集(Replica Sets)是额外的数据副本,是跨多个服务器同步数据的过程,复制集提供了冗余并增加了数据可用性,通过复制集可以对硬件故障和中断的服务进行恢复 复制集的优势 让数据更安全 高数据可用性(24*7) 灾难恢复 无停机维护(如备份.索引重建.故障转移) 读缩放(额外的副本读取) 副本集对应程序是透明的 复制集的特点 N个节点的群集 任何节点可作为主节点 所有写入操作都在主节点上 自动故障转移 自动恢复 复制集工作原理 1.MongoDB的复制集至少需要两个节点.其中一个是主

详解Redis Cluster集群

Redis Cluster是Redis的分布式解决方案,在Redis 3.0版本正式推出的,有效解决了Redis分布式方面的需求.当遇到单机内存.并发.流量等瓶颈时,可以采用Cluster架构达到负载均衡的目的.分布式集群首要解决把整个数据集按照分区规则映射到多个节点的问题,即把数据集划分到多个节点上,每个节点负责整个数据的一个子集. v功能介绍 1.0 数据自动分片 集群中每个节点都会负责一定数量的slot,每个key会映射到一个具体的slot,通过这种方式就可能找到key具体保存在哪个节点上

第14章 启动文件详解—零死角玩转STM32-F429系列

第14章     启动文件详解 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/firege 本章参考资料<STM32F4xx 中文参考手册>第十章-中断和事件:表 46. STM32F42xxx 和 STM32F43xxx 的向量表:MDK中的帮助手册—ARM Development Tools:用来查询ARM的汇编指令和编译器相关的指令. 14.1 启动文件简介 启动文件由汇编编写,是

第14章 启动文件详解

第14章     启动文件详解 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/firege 本章参考资料<STM32F4xx 中文参考手册>第十章-中断和事件:表 46. STM32F42xxx 和 STM32F43xxx 的向量表:MDK中的帮助手册-ARM Development Tools:用来查询ARM的汇编指令和编译器相关的指令. 14.1 启动文件简介 启动文件由汇编编写,是

使用LVS实现负载均衡原理及安装配置详解

转:http://www.cnblogs.com/liwei0526vip/p/6370103.html 使用LVS实现负载均衡原理及安装配置详解 负载均衡集群是 load balance 集群的简写,翻译成中文就是负载均衡集群.常用的负载均衡开源软件有nginx.lvs.haproxy,商业的硬件负载均衡设备F5.Netscale.这里主要是学习 LVS 并对其进行了详细的总结记录. 一.负载均衡LVS基本介绍 LB集群的架构和原理很简单,就是当用户的请求过来时,会直接分发到Director

Is It A Tree?------HDOJ杭电1325(两种方法,可以用也可以不用并查集!!!!!!详解)

Problem Description A tree is a well-known data structure that is either empty (null, void, nothing) or is a set of one or more nodes connected by directed edges between nodes satisfying the following properties. There is exactly one node, called the

并查集算法详解

更好的阅读体验 并查集算法详解 算法详解 维护类型 身为一个数据结构,我们的并查集,它的维护对象是我们的关注点. 并查集适合维护具有非常强烈的传递性质,或者是连通集合性质. 性质详解 传递性质 传递性,也就是具有传递效应的性质,比如说A传递给B一个性质或者条件,让B同样拥有了这个性质或者条件,那么这就是我们所说的传递性. 连通集合性质 连通集合性,和数学概念上的集合定义是差不多的, 比如说A和B同属一个集合,B和C同属一个集合,那么A,B,C都属于同一个集合.这就是我们所谓的连通集合性质. 算法

并查集详解(转)

并查集是我暑假从高手那里学到的一招,觉得真是太精妙的设计了.以前我无法解决的一类问题竟然可以用如此简单高效的方法搞定.不分享出来真是对不起party了.(party:我靠,关我嘛事啊?我跟你很熟么?) 来看一个实例,杭电1232畅通工程 首先在地图上给你若干个城镇,这些城镇都可以看作点,然后告诉你哪些对城镇之间是有道路直接相连的.最后要解决的是整幅图的连通性问题.比如随意给你两个点,让你判断它们是否连通,或者问你整幅图一共有几个连通分支,也就是被分成了几个互相独立的块.像畅通工程这题,问还需要修

并查集详解(转自一个很有才的大神)膜拜

并查集是我暑假从高手那里学到的一招,觉得真是太精妙的设计了.以前我无法解决的一类问题竟然可以用如此简单高效的方法搞定.不分享出来真是对不起party了.(party:我靠,关我嘛事啊?我跟你很熟么?) 来看一个实例,杭电1232畅通工程 首先在地图上给你若干个城镇,这些城镇都可以看作点,然后告诉你哪些对城镇之间是有道路直接相连的.最后要解决的是整幅图的连通性问题.比如随意给你两个点,让你判断它们是否连通,或者问你整幅图一共有几个连通分支,也就是被分成了几个互相独立的块.像畅通工程这题,问还需要修