数据结构-第六期——并查集(Python)

news2025/1/23 22:24:49

目录

认识并查集

经典应用:

应用场景

 并查集的操作

初始化 

代码实现 

合并 

代码实现 

查找

代码实现 

查找代码【图解】 

有多少个集(帮派)?

复杂度

查询的优化:路径压缩

【代码】用递归实现 

并查集:初始化、查找、合并代码 

蓝桥杯实战训练


认识并查集

  • 并查集(Disjoint Set) :一种非常精巧而实用的数据结构。
  • 用于处理不相交集合的合并问题

经典应用:

  • 连通子图
  • 最小生成树Kruskal算法
  • 最近公共祖先

应用场景

        场景一:有n个人,他们属于不同的帮派;已知这些人的关系,例如1号、2号是朋友,1号、3号也是朋友,那么他们都属于一个帮派。问有多少帮派,每人属于哪个帮派。
用并查集可以很简洁地表示这个关系。

        场景二:有n个人一起吃饭,有些人互相认识。认识的人想坐在一起,而不想跟陌生人坐。
例如A认识B,B认识C,那么A、B、C会坐在张桌子上。给出认识的人,问需要多少张桌子。

 并查集的操作

  • 初始化
  • 合并
  • 查找 

初始化 

  • 定义s[ ]是以结点i为元素的并查集。
  • 初始化:令s[i]=i。(联想:某人的号码是i,他属于帮派s[i])

 每个人都相互不认识

代码实现 

def init_set():
    #初始化
    for i in range (N): s. append(i)

# s = list (range (N))   #init_set ()可以简化为这一行

合并 

  • 加入第一个朋友关系(1,2)。

在并查集s中,把结点1合并到结点2,也就是把结点1的集1改成结点2的集2

 

  • 加入第二个朋友关系(1,3):

查找结点1的集,是2,递归查找元素2的集是2;

把元素2的集2合并到结点3的集3。此时,结点1、2、3都属于一个集

 

  • 加入第三个朋友关系(2,4):

代码实现 

# 合并x和y
def merge_set(x,y):
    x = find_set(x)    # 查找x的集合
    y = find_set(y)    # 查找y的集合
    if(x != y): s[x] = s[y]  # 若集合不同,合并

查找

 查找元素的集,是一个递归的过程,直到元素的值和它的集相等,就找到了根结点的集

代码实现 

def find_set(x):
    if x != s[x]:  return find_set(s[x])
    else:          return x

查找代码【图解】 

这棵搜索树,可能很细长,复杂度O(n),变成了一个链表,出现了树的“退化”现象。

有多少个集(帮派)?

  • 如果s[i]=i,这是一个根结点,是它所在的集的代表(帮主) ;
  • 统计根结点的数量,就是集的数量。

复杂度

查找find_set(),合并merge_set()的搜索深度是树的长度,复杂度都是O(n),性能差。
优化目标:优复杂度 ≈ O(1)

查询的优化:路径压缩

  • 查询程序find set():沿着搜索路径找到根结点,这条路径可能很长。
  • 优化:沿路径返回时,顺便把i所属的集改成根结点。下次再搜,复杂度是O( 1)

图片说明:沿路径返回时吗,3的集是4,不用改;继续返回到2,2的集是3,不是根节点,改成根节点4;继续返回到1,1的集是2,不是根节点,改成根节点4。 

【代码】用递归实现 

def find_set(x):    #有路径压缩优化的查询
    if(x != s[x]):               # 不等于自己的集
        s[x] = find_set(s[x])    # 把集改成根节点的集
    return s[x]

注:第一次要查n次,后面只需要查一次 

  • 路径压缩:整个搜索路径上的元素,在递归过程中,从元素i到根结点的所有元素,它们所属的集都被改为根结点。
  • 路径压缩不仅优化了下次查询,而且也优化了合并,因为合并时也用到了查询。

并查集:初始化、查找、合并代码 

def init_set():      #初始化
    for i in range (N):
        s. append(i)

def find_set(x):    #有路径压缩优化的查询
    if x != s[x]:               # 不等于自己的集
        s[x] = find_set(s[x])    # 把集改成根节点的集
    return s[x]

def merge_set(x,y):  #合并
    x = find_set(x)
    y = find_set(y)
    if x != y: s[x] = s[y]

注意:并查集虽然使用了递归来实现,但并不需要设置递归深度,因为并查集问题的深度很浅,不需要用到import sys   sys.setrecursionlimit(10000)来修改默认的最大递归深度。

蓝桥杯实战训练1

 蓝桥幼儿园lanqi ao0J题号1135

【题目描述】

        蓝桥幼儿园的学生是如此的天真无邪,以至于对他们来说,朋友的朋友就是自己的朋友。小明是蓝桥幼儿园的老师,这天他决定为学生们举办一个交友活动,活动规则如下:

小明会用红绳连接两名学生,被连中的两个学生将成为朋友。

        小明想让所有学生都互相成为朋友,但是蓝桥幼儿园的学生实在太多了,他无法用肉眼判断某两个学生是否为朋友。请你帮忙写程序判断某两个学生是否为朋友(默认自己和自己也是朋友)。

【输入描述】

第 1 行包含两个正整数N,M,其中 N 表示蓝桥幼儿园的学生数量,学生的编号分别为 1∼N。

之后的第 2∼M+1 行每行输入三个整数,op,x,y:

  • 如果 op = 1,表示小明用红绳连接了学生 x 和学生 y 。
  • 如果 op=2,请你回答小明学生 x 和 学生 y 是否为朋友。

1≤N,M≤2×10^5,1≤x,y≤N。

【输出描述】

对于每个 op=2 的输入,如果 x 和 y 是朋友,则输出一行 YES,否则输出一行 NO

【输入输出样式】

输入

5 5 
2 1 2
1 1 3
2 1 3
1 2 3 
2 1 2

输出

NO
YES
YES
def init_set(N):      #初始化
    for i in range (N):
        s. append(i)

def find_set(x):    #有路径压缩优化的查询
    if x != s[x]:               # 不等于自己的集
        s[x] = find_set(s[x])    # 把集改成根节点的集
    return s[x]

def merge_set(x,y):  #合并
    x = find_set(x)
    y = find_set(y)
    if x != y: s[x] = s[y]

n,m = map(int,input().split())
s  = []
init_set(10**6)    # 大小看题目要求,最大规模10**6
for i in range(m):
    op,x,y = map(int,input().split())
    if op == 1:
        merge_set(x,y)
    else:
        if find_set(x) == find_set(y):
            print("YES")
        else:
            print("NO")

复杂度:m个操作:O(m) 

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

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

相关文章

ES6之Promise

Promise是异步操作的一种解决方案 // 1.认识Promisedocument.addEventListener(click,()>{console.log(这里是异步的);});console.log(这里是同步的); Promise一般用来解决层层嵌套的回调函数&#xff08;回调地狱&#xff09;的问题 <!DOCTYPE html> <html lan…

JVM垃圾回收机制、JVM垃圾回收算法、JVM CMS与G1垃圾收集,JVM内存模型

C C 需要自己回收垃圾 重复回收&#xff1a; 回收掉别人的东西 忘记回收&#xff1a; 内存泄漏 Java虚拟机做自动化回收 垃圾回收器 Root Searching&#xff08;根可达&#xff09; GC Algorithms(垃圾回收算法) Mark-Sweep(标记清除) 缺点&#xff1a;碎片化&#xff0c;一…

Lua C接口编程(一)

引言 skynet 和 openresty 都是深度使用lua的典范&#xff0c;学习lua不经要学会基本语法&#xff0c;还要学会C语言与Lua交互。lua的一大优点就是能和c/c无缝连接&#xff0c;而且可以在不需要重复编译c/c的情况下可以修改lua文件并且起作用&#xff0c;当我们的项目文件很大…

【面试题】做了一份前端面试复习计划,保熟~

大厂面试题分享 面试题库前端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★地址&#xff1a;前端面试题库前言以前我看到面试贴就直接刷掉的&#xff0c;从不会多看一眼&#xff0c;直到去年 9 月份我开始准备面试时&#xff0c;才发现很多面试经验贴…

Kubernetes(k8s) 笔记总结(二)

提示&#xff1a;针对kubernetes的工作均衡学习。 文章目录1. Kubernetes 创建资源方式2. Kubernetes 操作NameSpace3. Kubernetes的 Pod应用3.1 Pod的 解释3.2 通过命令行来创建一个pod3.3 配置文件方式创建一个Pod3.4 dashboard 可视化操作Pod3.5 针对Pod的一些细节操作3.6 P…

如何评估PMO (项目管理办公室)的实施效果?

使用有效的组织战略、方法和技术&#xff0c;可以成功启动并制度化企业范围的PMO (项目管理办公室)。 一个企业范围内的PMO可以使用成熟的技术启动。 但你应该开发和使用适当的评估工具&#xff0c;以确定你的PMO实施的项目管理过程的有效性。这些工具可以包括正式的管理评估…

黑马学ElasticSearch(四)

目录&#xff1a; &#xff08;1&#xff09;RestClient操作文档-新建文档 &#xff08;2&#xff09;RestClient操作文档-查询文档 &#xff08;3&#xff09;RestClient操作文档-更新文档 &#xff08;4&#xff09;RestClient操作文档-删除文档 &#xff08;5&#xff…

包管理工具详解npm 、 yarn 、 cnpm 、 npx 、 pnpm

1、包管理工具npm &#xff08;1&#xff09;包管理工具npm&#xff1a; Node Package Manager&#xff0c;也就是Node包管理器&#xff1b;但是目前已经不仅仅是Node包管理器了&#xff0c;在前端项目中我们也在使用它来管理依赖的包&#xff1b;比如vue、vue-router、vuex、…

数据分析-深度学习 Day4

本专栏主本专栏主要介绍和讲解李宏毅老师最新2021春季机器学习课程相关内容&#xff0c;如有记录错误&#xff0c;或理解不对&#xff0c;欢迎留言批评指正...youtube课程地址&#xff1a;&#xff08;实时更新&#xff09;ML 2021 Springspeech.ee.ntu.edu.tw/~hylee/ml/2021-…

sxs卡数据怎么恢复?分享三种恢复方案

说起sxs卡&#xff0c;你们是否有所了解呢&#xff1f;sxs卡具有很好的传输性能&#xff0c;能够存储照片和视频数据&#xff0c;主要被放置在索尼XDCAM EX型摄像机上。而在使用sxs卡设备过程中&#xff0c;难免和其他设备一样&#xff0c;容易出现数据丢失情况。而如果丢失的是…

在虚拟机上安装win11

虚拟机版本呢vmware16win11镜像&#xff1a;zh-cn_windows_11_business_editions_version_22h2_updated_dec_2022_x64_dvd_0b26ca48.isoPE镜像&#xff1a;EasyU_v3.7.iso 通过优启通工具制作两个光驱&#xff0c;第一个选pe的iso&#xff0c;第二个选win11的iso点击开启虚拟机…

(day5) 自学Java——ArrayList集合

目录 1. ArrayList 2.集合练习 (1)添加字符串和整数&#xff0c;并遍历 (2)添加学生对象并遍历 (3)查找用户是否存在 (4)返回多个数据 1. ArrayList 数组有个致命的弱点&#xff0c;那就是创建时需要指定其长度&#xff0c;并且在使用时长度不可改变。 在Java教程中知道…

[ 数据结构 ] 图(Graph)--------深度优先、广度优先遍历

0 基本介绍 为什么要有图? 无论是线性表还是树结构,局限于表示一个直接前驱和一个直接后继的关系(一对一/一对多),当我们需要表示多对多的关系时&#xff0c; 这里我们就用到了图 节点间的连接成为边,节点称为顶点,一个顶点到另一个顶点所经过的边叫路径,边有方向的叫有向图,…

js逆向-某动网演出数据获取

声明 本文仅供学习参考&#xff0c;如有侵权可私信本人删除&#xff0c;请勿用于其他途径&#xff0c;违者后果自负&#xff01; 如果觉得文章对你有所帮助&#xff0c;可以给博主点击关注和收藏哦&#xff01; 前言 目标网站&#xff1a;aHR0cHM6Ly93d3cuc2hvd3N0YXJ0LmNv…

如何远程连接Linux系统服务器

Linux服务器远程连接方法这里给大家普及一下Linux服务器&#xff0c;是一台安装Ubuntu系统的工作站。这类服务器大部分用于程序员开发编程使用&#xff0c;说简单点就是拿来敲代码的。通常需要借助远程连接工具来连接Linux远程服务器&#xff0c;如xshell&#xff1b;putty&…

PostgreSQL实战之物理复制和逻辑复制(五)

目录 PostgreSQL实战之物理复制和逻辑复制&#xff08;五&#xff09; 5 流复制主备切换 5.1 判断主备角色的五种方法 5.2 主备切换之文件触发方式 5.3 主备切换之pg_ctl promote方式 5.4 pg_rewind PostgreSQL实战之物理复制和逻辑复制&#xff08;五&#xff09; 5 流…

Vue作业

文章目录作业1作业2作业3作业4作业1 作业&#xff1a;需要用data保存&#xff1a;商品名、单价、数量&#xff0c;然后显示到页面上&#xff0c;点击按钮可以变更数量&#xff0c;最小值1&#xff0c;减按钮不可用&#xff0c;最大值20&#xff0c;隐藏按钮 总价格应该是 单价…

酒业“新物种”的新思维:用户、品牌、模式

【潮汐商业评论/原创】中国的酒文化源远流长。古人有一万种喝酒的理由&#xff0c;或聚会畅饮&#xff0c;或独酌解忧&#xff0c;而餐桌是酒最常出现的地方。如今&#xff0c;与酒相关的场景日益多元&#xff0c;往往洋溢着青春的气息。一顶帐篷&#xff0c;三两好友围坐&…

一、数据仓库基础理论

数据仓库基础理论一、数据仓库1、概念2、数据仓库分层结构3、为什么要分层二、数据集市三、数据湖1、数据湖和数据仓库一、数据仓库 1、概念 数据仓库&#xff08;Data Warehouse, DW&#xff09;&#xff1a;一个面向主题的、集成的、非易失的、反应历史变化的、用来支持企业…

哈弗品牌发布新能源越野新品类车型:H-DOG

1月6日&#xff0c;哈弗品牌新能源车型哈弗H-DOG在海口新能源车展亮相。哈弗H-DOG针对用户5天通勤、2天郊野、e享时刻三大使用场景打磨&#xff0c;满足用户“可城、可野、可电”的用车需求&#xff0c;是哈弗品牌在新能源轻越野上的全新探索。• 哈弗H-DOG采用了全新的潮野力量…