并查集(还有反集也在)

 一.定义


定义:
并查集是一种树型的数据结构,用于处理一些不相交集合的合并及查询问题(即所谓的并、查)。比如说,我们可以用并查集来判断一个森林中有几棵树、某个节点是否属于某棵树等。

主要构成:
并查集主要由一个整型数组pre[ ]和两个函数find( )、join( )构成。
数组 pre[ ] 记录了每个点的前驱节点是谁,函数 find(x) 用于查找指定节点 x 属于哪个集合,函数 join(x,y) 用于合并两个节点 x 和 y 。

作用:
并查集的主要作用是求连通分支数(如果一个图中所有点都存在可达关系(直接或间接相连),则此图的连通分支数为1;如果此图有两大子图各自全部可达,则此图的连通分支数为2……)

 二.代码

find( )函数的定义与实现

故事引入:
子夜,小昭于骊山下快马送信,发现一头戴竹笠之人立于前方,其形似黑蝠,倒挂于树前,甚惧,正系拔剑之时,只听四周悠悠传来:“如此夜深,姑凉竟敢擅闯明教,何不下坐陪我喝上一盅?”。小昭听闻,后觉此人乃明教四大护法之一的青翼蝠王韦一笑,答道:“在下小昭,乃紫衫龙王之女”。蝠王轻惕,急问道:“尔等既为龙王之女,故同为明教中人。敢问阁下教主大名,若非本教中人,于明教之地肆意走动那可是死罪!”。小昭吓得赶紧打了个电话问龙王:“龙王啊,咱教主叫啥名字来着?”,龙王答道:“吾教主乃张无忌也!”,小昭遂答蝠王:“张无忌!”。蝠王听后,抱拳请礼以让之。
在上面的情境中,小昭向他的上级(紫衫龙王)请示教主名称,龙王在得到申请后也向他的上级(张无忌)请示教主名称,此时由于张无忌就是教主,因此他直接反馈给龙王教主名称是“张无忌”。同理,青翼蝠王也经历了这一请示过程。
在并查集中,用于查询各自的教主名字的函数就是我们的find()函数。find(x)的作用是用于查找某个人所在门派的教主,换言之就是用于对某个给定的点x,返回其所属集合的代表。

实现:
首先我们需要定义一个数组:int pre[1000]; (数组长度依题意而定)。这个数组记录了每个人的上级是谁。这些人从0或1开始编号(依题意而定)。比如说pre[16]=6就表示16号的上级是6号。如果一个人的上级就是他自己,那说明他就是教主了,查找到此结束。也有孤家寡人自成一派的,比如欧阳锋,那么他的上级就是他自己。
每个人都只认自己的上级。比如小昭只知道自己的上级是紫衫龙王。教主是谁?不认识!要想知道自己教主的名称,只能一级级查上去。因此你可以视find(x)这个函数就是找教主用的。
下面给出这个函数的具体实现:

int find(int x)					//查找x的教主
{while(pre[x] != x)			//如果x的上级不是自己(则说明找到的人不是教主)x = pre[x];				//x继续找他的上级,直到找到教主为止return x;					//教主驾到~~~
}

 

join( )函数的定义与实现


故事引入:
虚竹和周芷若是我个人非常喜欢的两个人物,他们的教主分别是玄慈方丈和灭绝师太,但是显然这两个人属于不同门派,但是我又不想看到他们打架。于是,我就去问了下玄慈和灭绝:“你看你们俩都没头发,要不就做朋友吧”。他们俩看在我的面子上同意了,这一同意非同小可,它直接换来了少林和峨眉的永世和平。

实现:
在上面的情景中,两个已存的不同门派就这样完成了合并。这么重大的变化,要如何实现?要改动多少地方?其实很简单,我对玄慈方丈说:“大师,麻烦你把你的上级改为灭绝师太吧。这样一来,两派原先所有人员的教主就都变成了师太,于是下面的人们也就不会打起来了!反正我们关心的只是连通性,门派内部的结构不要紧的”。玄慈听后立刻就不乐意了:“我靠,凭什么是我变成她手下呀,怎么不反过来?我抗议!”。抗议无效,我安排的,最大。反正谁加入谁效果是一样的,我就随手指定了一个,join()函数的作用就是用来实现这个的。

join(x,y)的执行逻辑如下:
1、寻找 x 的代表元(即教主);
2、寻找 y 的代表元(即教主);
3、如果 x 和 y 不相等,则随便选一个人作为另一个人的上级,如此一来就完成了 x 和 y 的合并。
下面给出这个函数的具体实现:

void join(int x,int y)                     //我想让虚竹和周芷若做朋友
{int fx=find(x), fy=find(y);            //虚竹的老大是玄慈,芷若MM的老大是灭绝if(fx != fy)                           //玄慈和灭绝显然不是同一个人pre[fx]=fy;                        //方丈只好委委屈屈地当了师太的手下啦
}

总结


1、用集合中的某个元素来代表这个集合,则该元素称为此集合的代表元;
2 、一个集合内的所有元素组织成以代表元为根的树形结构;
3 、对于每一个元素 x,pre[x] 存放 x 在树形结构中的父亲节点(如果 x 是根节点,则令pre[x] = x);
4 、对于查找操作,假设需要确定 x 所在的的集合,也就是确定集合的代表元。可以沿着pre[x]不断在树形结构中向上移动,直到到达根节点。
因此,基于这样的特性,并查集的主要用途有以下两点:
1、维护无向图的连通性(判断两个点是否在同一连通块内,或增加一条边后是否会产生环);
2、用在求解最小生成树的Kruskal算法里。


一般来说,一个并查集对应三个操作:
1、初始化( Init()函数 )
2、查找函数( Find()函数 )
3、合并集合函数( Join()函数 )

#include<bits/stdc++.h>
using  namespace std;
#define int long long
int n,m;
int pre[10007];
void init(){for(int i=1;i<=n;i++){pre[i]=i;//每个结点的上级都是自己 }
}
int find(int x){ //查找结点 x的根结点 if(pre[x]!=x){pre[x]=find(pre[x]);//递归出口:x的上级为 x本身,则 x为根结点 }return pre[x];//递归查找 
}
void join(int x,int y){int fx=find(x);//寻找 x的代表元int fy=find(y);//寻找 y的代表元if(fx!=fy){//不同集合则合并pre[fx]=fy;}
}
bool isSame(int x,int y){return find(x)==find(y);
}
signed main(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin>>n>>m;init();while(m--){int num;cin>>num;if(num==1){int x,y;cin>>x>>y;join(x,y);}else{int x,y;cin>>x>>y;if(isSame(x,y)==0){cout<<"N"<<endl;}else{cout<<"Y"<<endl;}}}system("pause");return 0;
}

三.例题一 

 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m,k;
int pre[10010];
void init(){for(int i=1;i<=n;i++){pre[i]=i;}
}
int find(int x){if(pre[x]!=x){pre[x]=find(pre[x]);}return pre[x];
}
void join(int x,int y){int fx=find(x);int fy=find(y);if(fx!=fy){pre[fx]=fy;}
}
bool issame(int x,int y){return find(x)==find(y);
}
int main(){cin>>n>>m>>k;init();while(m--){int a,b;cin>>a>>b;join(a,b);}while(k--){int a,b;cin>>a>>b;if(issame(a,b)){cout<<"Yes"<<endl;}else{cout<<"No"<<endl;}}system("pause");return 0;
}

  

四.例题二 (加反集)

 

 

关于反集

我也是做这道题才知道的

如果a和b是敌人,合并n+b和a,n+a和b

如果c和a是敌人,合并n+c和a,n+a和c

那么b和c就并在一起了

这样就符合了题目敌人的敌人是朋友的规则

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,k;
int pre[10010];
map<int,int> mp;
void init(){for(int i=1;i<=2*n;i++){pre[i]=i;//这里初始化为2*n}
}
int find(int x){if(pre[x]!=x){pre[x]=find(pre[x]);}return pre[x];
}
void join(int x,int y){int fx=find(x);int fy=find(y);if(fx!=fy){pre[fx]=fy;}
}
int main(){cin>>n>>k;init();while(k--){string s;cin>>s;int a,b;cin>>a>>b;if(s=="F"){join(a,b);}else if(s=="E"){join(n+a,b);join(n+b,a);}}int cnt=0;for(int i=1;i<=n;i++){if(pre[i]==i) cnt++;}cout<<cnt<<endl;system("pause");return 0;
}

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/42622.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PHP-实例-文件上传

1 需求 2 basename 在 PHP 中&#xff0c;basename() 函数用于返回路径中的文件名部分。如果路径中包含了文件扩展名&#xff0c;则该函数也会返回它。如果路径的结尾有斜杠&#xff08;/&#xff09;或反斜杠&#xff08;\&#xff09;&#xff0c;则 basename() 函数会返回空…

Android计算器界面的设计——表格布局TableLayout实操

目录 任务目标任务分析任务实施 任务目标 使用TextView、Button等实现一个计算器界面&#xff0c;界面如图1所示。 图1 计算器界面效果图 任务分析 界面整体使用表格布局&#xff0c;第一行使用一个TextView控件&#xff0c;横跨4列&#xff0c;中间4行4列&#xff0c;最后一…

Laravel HTTP客户端:网络请求的瑞士军刀

标题&#xff1a;Laravel HTTP客户端&#xff1a;网络请求的瑞士军刀 Laravel的HTTP客户端是一个功能强大的工具&#xff0c;它提供了一种简洁、直观的方式来发送HTTP请求。无论是与外部API集成&#xff0c;还是进行网络数据抓取&#xff0c;Laravel的HTTP客户端都能满足你的需…

小红书选品中心商家采集 小红书商家电话采集软件

可采集名称销量评分联系方式等 需要有1000粉丝以上已实名认证过的小红书达人才可以使用 以下是一个示例程序&#xff0c;可以用于批量获取小红书选品中心商家的信息&#xff1a; import requestsdef get_merchants(page_num):url f"https://www.xiaohongshu.com/selec…

git 添加本地分支, clean

//以develop为源创建本地分支fromdevelop git checkout -b fromdevelop git add . git commit -m "local" git checkout -b local/dev //切换到远程分支. git checkout dev git clean_git clean -f -d-CSDN博客 git clean -f -d #删除当前目录下没有被track…

RAC spfile 坑 +data INSTANCE_NUMBER thread x is mounted by another instance

RAC相关三个参数 thread reset 就可以默认 instance_number 需要单独设置 sid‘SIDX’ cluster_database boolean TRUE SQL> alter system reset instance_number sid* scopespfile; alter system reset instance_number sid* scopespfile …

解析Torch中`Transformer`

解析torch官方代码脚本文件&#xff1a;transformer.py。版本&#xff1a;1.9.1cu111。 首先查看《Torch中多头注意力MultiheadAttention的中文注释》解析&#xff1b; 最后查看下方transformer解析。 话不多说&#xff0c;看代码吧&#xff01; import copy from typing imp…

Vue的学习之class与style绑定

<!DOCTYPE html> <html><head><meta charset"utf-8"><title>Vue的学习</title><script src"vue.js" type"text/javascript" charset"utf-8"></script></head><body><…

如何在std::map中查找元素

在std::map中查找元素可以通过几种不同的方式完成&#xff0c;但最常用的方法是使用find成员函数。std::map是一个基于键值对的关联容器&#xff0c;其中每个元素都是一个键值对。键是唯一的&#xff0c;并且用于排序和快速查找。 使用find成员函数 find成员函数接受一个键作…

io流 多线程

目录 一、io流 1.什么是io流 2.流的方向 i.输入流 ii.输出流 3.操作文件的类型 i.字节流 1.拷贝 ii.字符流 ​3.字符流输出流出数据 4.字节流和字符流的使用场景 5.练习 6.缓冲流 1.字节缓冲流拷贝文件 2.字符缓冲流特有的方法 1.方法 2.总结 7.转换流基本用法…

第2集《修习止观坐禅法要》

请打开补充讲表第一面&#xff0c;附表一、念佛摄心方便法。 我们前面讲到修止&#xff0c;就是善取所缘境的相貌&#xff0c;然后心于所缘&#xff0c;专一安住&#xff1b;心于所缘&#xff0c;相续安住&#xff1b;达到心一境性的目的。 站在修学净土的角度&#xff0c;他…

FastAPI+SQLAlchemy数据库连接

FastAPISQLAlchemy数据库连接 目录 FastAPISQLAlchemy数据库连接配置数据库连接创建表模型创建alembic迁移文件安装初始化编辑env.py编辑alembic.ini迁移数据库 视图函数查询 配置数据库连接 # db.py from sqlalchemy import create_engine from sqlalchemy.orm import sessio…

9、程序化创意

程序化创意 程序化创意&#xff08;Programmatic Creative&#xff09;是指通过自动化的方式制作并优化广告创意&#xff0c;以提高广告效果。针对不同受众的多样化需求&#xff0c;以及同一受众在不同场景下的消费需求&#xff0c;程序化创意能够自动生成个性化的精准创意&am…

《C语言》预处理

文章目录 一、预定义符号二、#define定义常量三、#define定义宏四、宏更函数的对比五、#和##1、#运算符2、##运算符 一、预定义符号 C语言设置了一些预定义符号&#xff0c;可以直接使用&#xff0c;在预处理期间进行处理的。 __FILE__//进行编译的源文件 __LINE__//文件当前的…

在网站存在漏洞的情况下强化安全防御

一、引言 网络安全是一个持续的战斗&#xff0c;尤其是在网站存在已知或未知漏洞的情况下。本文将探讨如何在网站存在漏洞的情况下&#xff0c;采取有效措施进行安全防御。 二、理解漏洞 首先&#xff0c;我们需要理解网站的漏洞。这些可能包括SQL注入、跨站脚本&#xff08…

【数据结构与算法】插入排序

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;《数据结构与算法》 期待您的关注 ​

深入Laravel服务容器:构建灵活应用的秘诀

标题&#xff1a;深入Laravel服务容器&#xff1a;构建灵活应用的秘诀 Laravel框架的服务容器是一个强大的工具&#xff0c;它负责管理类的依赖关系和执行依赖注入&#xff08;DI&#xff09;。服务容器是Laravel依赖注入系统的核心&#xff0c;使得应用组件之间的耦合度降低&…

一周速递|全球车联网产业动态(2024年7月7日)

政策法规 1、7月5日&#xff0c;工业和信息化部部长金壮龙在新闻发布会上表示&#xff0c;新兴产业要培育壮大。对新材料、人工智能、智能网联新能源汽车、新型储能、氢能、生物制造、商业航天、低空经济等新兴产业&#xff0c;要继续用好国内大市场和丰富应用场景&#xff0c…

人工智能、机器学习、神经网络、深度学习和卷积神经网络的概念和关系

人工智能&#xff08;Artificial Intelligence&#xff0c;缩写为AI&#xff09;--又称为机器智能&#xff0c;是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。 人工智能是智能学科重要的组成部分&#xff0c;它企图了解智能的实质…

【问题解决】 pyocd 报错 No USB backend found 的解决方法

pyocd 报错 No USB backend found 的解决方法 本文记录了我在Windows 10系统上遇到的pyocd命令执行报错——No USB backend found 的分析过程和解决方法。遇到类似问题的朋友可以直接参考最后的解决方法&#xff0c;向了解问题发送原因的可以查看原因分析部分。 文章目录 pyoc…