蓝桥杯刷题记录【并查集001】(2024)

news2025/5/9 14:40:54

主要内容:并查集

并查集

并查集的题目感觉大部分都是模板题,上板子!!

class UnionFind:
    def __init__(self, n):
        self.pa = list(range(n))
        self.size = [1]*n 
        self.cnt = n
    
    def find(self, x):
        if self.pa[x] != x:
            self.pa[x] = self.find(self.pa[x])
        return self.pa[x]
    
    def merge(self, x, y):
        fx = self.find(x)
        fy = self.find(y)
        if fx == fy:
            return False
        self.pa[fx] = fy 
        self.size[fy] += self.size[fx]
        self.cnt -= 1
        return True 
    
    def is_same(self, x, y):
        return self.find(x) == self.find(y)

merge函数用于判断x,y是否联通,如果联通return False。

lanqiao19719吊坠

# 并查集模板
class UnionFind:
    def __init__(self, n):
        self.pa = list(range(n))
        self.size = [1]*n 
        self.cnt = n
    
    def find(self, x):
        if self.pa[x] != x:
            self.pa[x] = self.find(self.pa[x])
        return self.pa[x]
    
    def merge(self, x, y):
        fx = self.find(x)
        fy = self.find(y)
        if fx == fy:
            return False
        self.pa[fx] = fy 
        self.size[fy] += self.size[fx]
        self.cnt -= 1
        return True 
    
    def is_same(self, x, y):
        return self.find(x) == self.find(y)

n, m = map(int, input().split()) # 输入处理

strings = [] # 记录字符串
for _ in range(n):
    strings.append(input())

# 边权为这两个字符串的最长公共子串的长度,可以按环形旋转改变起始位置,但不能翻转
def f(s):
    m = len(s)
    # 两个字符串拼接起来
    s_concat = s + s 
    # 字典,键为子串长度,值为子串
    suffix_dict = {}
    for i in range(m):
        rotated = s_concat[i:i+m]
        for k in range(1, m):
            # 旋转之后的子串
            suffix = rotated[-k:]
            if k not in suffix_dict:
                suffix_dict[k] = set()
            suffix_dict[k].add(suffix)
    return suffix_dict 

suffix_dicts = []
for s in strings:
    suffix_dicts.append(f(s))

# 建图,包括边权,连接点
edges = []
for i in range(n):
    for j in range(i+1, n):
        max_ij_k = 0 
        for k in range(m, -1, -1):
            suffix_set_i = suffix_dicts[i].get(k, set())
            suffix_set_j = suffix_dicts[j].get(k, set())
            # 如果两个集合相交不为空,记录max_ij_k为k,因为是逆序的,所以直接记录并break
            if suffix_set_i & suffix_set_j:
                max_ij_k = k 
                break 
        weight = max_ij_k
        edges.append((weight, i, j))
# 边权从小到大排序
edges.sort(reverse=True, key=lambda x : x[0])
uf = UnionFind(n)
# ans记录值,cnt记录次数
ans = 0 
cnt = 0
for weight, i, j in edges:
    if uf.merge(i, j):
        ans += weight
        cnt += 1
        # 临界
        if cnt == n-1:
            break 
print(ans)








3493. 属性图

class UnionFind:
    def __init__(self, n):
        self.pa = list(range(n))
        self.size = [1]* n 
        self.cnt = n 
    
    def find(self, x):
        if self.pa[x] != x:
            self.pa[x] = self.find(self.pa[x])
        return self.pa[x]
    
    def merge(self, x, y):
        fx = self.find(x)
        fy = self.find(y)
        if fx == fy:
            return False 
        self.pa[fx] = fy 
        self.size[fy] += self.size[fx]
        self.cnt -= 1
        return True 
    
    def is_same(self, x, y):
        return self.find(x) == self.find(y)


class Solution:
    def numberOfComponents(self, properties: List[List[int]], k: int) -> int:
        sets = list(map(set, properties))
        uf = UnionFind(len(properties))
        for i, a in enumerate(sets):
            for j, b in enumerate(sets[:i]):
                if len(a&b) >= k:
                    uf.merge(i, j)
        return uf.cnt

思路:并查集,先利用集合的特性去重,根据properties的长度实例化并查集,双重循环得到集合a和集合b,根据题目要求当 intersect(properties[i], properties[j]) >= k(其中 i 和 j 的范围为 [0, n - 1] 且 i != j),节点 i 和节点 j 之间有一条边,即当满足条件时,将i,j连起来,并在merge函数中self.cnt -= 1。最终返回uf.cnt就行。

1971. 寻找图中是否存在路径

class UnionFind:
    def __init__(self, n):
        self.pa = list(range(n))
        self.size = [1]*n 
        self.cnt = n
    
    def find(self, x):
        if self.pa[x] != x:
            self.pa[x] = self.find(self.pa[x])
        return self.pa[x]
    
    def merge(self, x, y):
        fx = self.find(x)
        fy = self.find(y)
        if fx == fy:
            return False
        self.pa[fx] = fy 
        self.size[fy] += self.size[fx]
        self.cnt -= 1
        return True 
    
    def is_same(self, x, y):
        return self.find(x) == self.find(y)

class Solution:
    def validPath(self, n: int, edges: List[List[int]], source: int, destination: int) -> bool:
        uf = UnionFind(n)
        for i, j in edges:
            uf.merge(i, j)
        return uf.is_same(source, destination)

实例化一个并查集,遍历edges中的i,j并连起来,遍历结束就使用is_same()函数进行判断是否连在一起。

200. 岛屿数量

class UnionFind:
    def __init__(self, n):
        self.pa = list(range(n))
        self.size = [1]*n 
        self.cnt = n
    
    def find(self, x):
        if self.pa[x] != x:
            self.pa[x] = self.find(self.pa[x])
        return self.pa[x]
    
    def merge(self, x, y):
        fx = self.find(x)
        fy = self.find(y)
        if fx == fy:
            return False
        self.pa[fx] = fy 
        self.size[fy] += self.size[fx]
        self.cnt -= 1
        return True 
    
    def is_same(self, x, y):
        return self.find(x) == self.find(y)

class Solution:
    def numIslands(self, grid: List[List[str]]) -> int:
        n = len(grid)
        m = len(grid[0])
        uf = UnionFind(m*n)
        ocean = 0
        for i in range(n):
            for j in range(m):
                if grid[i][j] == "0":
                    ocean += 1
                else:
                    # 向下查看
                    if i < n-1 and grid[i+1][j] == "1":
                        uf.merge(i*m+j, (i+1)*m+j)
                    # 向右查看
                    if j < m-1 and grid[i][j+1] == "1":
                        uf.merge(i*m+j, i*m+j+1)
        return uf.cnt - ocean

思路:获得grid的高n宽m,通过n*m实例化并查集,将grid中的每个元素当作一个点看,然后使用ocean记录海水的熟练,当grid[i][j]==“1”时,向下向右查看,如果下面是1将当前位置i*m+j和(i+1)*m+j连起来,当右边是1将当前位置和i*m+j+1连起来。最终返回uf.cnt-ocean即为所求答案。

1631. 最小体力消耗路径

class UnionFind:
    def __init__(self, n):
        self.pa = list(range(n))
        self.size = [1]* n 
        self.cnt = n 
    
    def find(self, x):
        if self.pa[x] != x:
            self.pa[x] = self.find(self.pa[x])
        return self.pa[x]
    
    def merge(self, x, y):
        fx = self.find(x)
        fy = self.find(y)
        if fx == fy:
            return False 
        self.pa[fx] = fy 
        self.size[fy] += self.size[fx]
        self.cnt -= 1
        return True 
    
    def is_same(self, x, y):
        return self.find(x) == self.find(y)

class Solution:
    def minimumEffortPath(self, heights: List[List[int]]) -> int:
        n = len(heights)
        m = len(heights[0])
        uf = UnionFind(n*m)
        edges = []
        dirs = (0, 1, 0)
        for i in range(n):
            for j in range(m):
                for a, b in pairwise(dirs):
                    x = i + a
                    y = j + b 
                    if 0 <= x < n and 0 <= y < m:
                        edges.append((abs(heights[i][j] - heights[x][y]), i*m+j, x*m+y))
        edges.sort() # 求最小
        for h, i, j in edges:
            uf.merge(i, j)
            if uf.is_same(0, m*n-1):
                return h 
        return 0
        

思路:和岛屿数量思路类似,通过n*m实例化并查集,edges记录i,j和x,y之间的高度之差绝对值。根据这个值进行排序edges,然后开始遍历edges,每次遍历将i,j连起来,并判断起点0和m*n-1是否连起来了,连起来了就直接return h因为edges是在此之前排过序的。

924. 尽量减少恶意软件的传播

class UnionFind:
    def __init__(self, n):
        self.pa = list(range(n))
        self.size = [1]* n 
        self.cnt = n 
    
    def find(self, x):
        if self.pa[x] != x:
            self.pa[x] = self.find(self.pa[x])
        return self.pa[x]
    
    def merge(self, x, y):
        fx = self.find(x)
        fy = self.find(y)
        if fx == fy:
            return False 
        self.pa[fx] = fy 
        self.size[fy] += self.size[fx]
        self.cnt -= 1
        return True 
    
    def is_same(self, x, y):
        return self.find(x) == self.find(y)

class Solution:
    def minMalwareSpread(self, graph: List[List[int]], initial: List[int]) -> int:
        n = len(graph)
        m = len(graph[0])
        uf = UnionFind(n)
        for i in range(n):
            for j in range(i + 1, n):
                graph[i][j] and uf.merge(i, j)
        cnt = Counter(uf.find(x) for x in initial)
        ans, mx = n, 0
        for x in initial:
            root = uf.find(x)
            if cnt[root] > 1:
                continue
            sz = uf.size[root]
            if sz > mx or (sz == mx and x < ans):
                ans = x
                mx = sz
        return min(initial) if ans == n else ans
        

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

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

相关文章

基于BusyBox构建ISO镜像

1. 准备 CentOS 7.9 3.10.0-957.el7.x86_64VMware Workstation 建议&#xff1a;系统内核<3.10.0 使用busybox < 1.33.2版本 2. 安装busybox # 安装依赖 yum install syslinux xorriso kernel-devel kernel-headers glibc-static ncurses-devel -y# 下载 wget https://…

Multisim14.3的安装步骤

Multisim14.3的安装步骤 安装包链接 右击Install.exe&#xff0c;以管理员身份运行 激活前关闭杀毒软件 右击&#xff0c;以管理员身份运行 依次右键【Base Edition】、【Full Edition】、【Power ProEdition】、【Full Edition】、【Power ProEdition】&#xff0c;选择【…

搭建环境-opencv-qt

CMake Error at cmake/OpenCVCompilerOptimizations.cmake:647 (message): Compiler doesnt support baseline optimization flags: Call Stack (most recent call first): cmake/OpenCVCompilerOptions.cmake:344 (ocv_compiler_optimization_options) CMakeList 解决方…

SparkAudio 是什么,和其他的同类 TTS 模型相比有什么优势

欢迎来到涛涛聊AI 在当今数字化时代&#xff0c;音频处理技术已经成为人们生活和工作中不可或缺的一部分。无论是制作有声读物、开发语音助手&#xff0c;还是进行影视配音&#xff0c;我们都离不开高效、精准的音频处理工具。然而&#xff0c;传统的音频处理技术往往存在诸多…

Java 8 到 Java 21 系列之 Optional 类型:优雅地处理空值(Java 8)

Java 8 到 Java 21 系列之 Optional 类型&#xff1a;优雅地处理空值&#xff08;Java 8&#xff09; 系列目录 Java8 到 Java21 系列之 Lambda 表达式&#xff1a;函数式编程的开端&#xff08;Java 8&#xff09;Java 8 到 Java 21 系列之 Stream API&#xff1a;数据处理的…

py文件打包为exe可执行文件,涉及mysql连接失败

py文件打包为exe可执行文件&#xff0c;涉及mysql连接失败 项目场景&#xff1a;使用flask框架封装算法接口&#xff0c;并使用pyinstaller打包为exe文件。使用pyinstaller打包多文件的场景&#xff0c;需要自己手动去.spec文件中添加其他文件&#xff0c;推荐使用auto-py-to-e…

Ubuntu 系统 Docker 中搭建 CUDA cuDNN 开发环境

CUDA 是 NVIDIA 推出的并行计算平台和编程模型&#xff0c;利用 GPU 多核心架构加速计算任务&#xff0c;广泛应用于深度学习、科学计算等领域。cuDNN 是基于 CUDA 的深度神经网络加速库&#xff0c;为深度学习框架提供高效卷积、池化等操作的优化实现&#xff0c;提升模型训练…

win10彻底让图标不显示在工具栏

关闭需要不显示的软件 打开 例此时我关闭了IDEA的显示 如果说只是隐藏&#xff0c;鼠标拖动一个道理 例QQ 如果说全部显示不隐藏

人脸识别和定位别的签到系统

1、功能 基于人脸识别及定位的宿舍考勤管理小程序 &#xff08;用户&#xff1a;宿舍公告、宿舍考勤查询、宿舍考勤&#xff08;人脸识别、gps 定 位&#xff09;、考勤排行、请假申请 、个人中心 管理员&#xff1a;宿舍管理、宿舍公告管理 学生信息管理、请假审批、发布宿舍…

基于YOLOv8的热力图生成与可视化:支持自定义模型与置信度阈值的多维度分析

目标检测是计算机视觉领域的重要研究方向&#xff0c;而YOLO&#xff08;You Only Look Once&#xff09;系列算法因其高效性和准确性成为该领域的代表性方法。YOLOv8作为YOLO系列的最新版本&#xff0c;在目标检测任务中表现出色。然而&#xff0c;传统的目标检测结果通常以边…

Design Compiler:库特征分析(ALIB)

相关阅读 Design Compilerhttps://blog.csdn.net/weixin_45791458/category_12738116.html?spm1001.2014.3001.5482 简介 在使用Design Compiler时&#xff0c;可以对目标逻辑库进行特征分析&#xff0c;并创建一个称为ALIB的伪库&#xff08;可以被认为是缓存&#xff09;&…

便携式雷达信号模拟器 —— 打造实战化电磁环境的新利器

在现代战争中&#xff0c;雷达信号的侦察与干扰能力直接关系到作战的成败。为了提升雷达侦察与干扰装备的实战能力&#xff0c;便携式雷达信号模拟器作为一款高性能设备应运而生&#xff0c;为雷达装备的训练、测试和科研提供了不可或缺的支持。 核心功能 便携式雷达信号模拟…

CentOS Linux升级内核kernel方法

目录 一、背景 二、准备工作 三、升级内核 一、背景 某些情况需要对Linux发行版自带的内核kernel可能版本较低&#xff0c;需要对内核kernel进行升级。例如&#xff1a;CentOS 7.x 版本的系统默认内核是3.10.0&#xff0c;该版本的内核在Kubernetes社区有很多已知的Bug&#…

【C++】多态功能细节问题分析

多态是在不同继承关系的类对象去调用同一函数&#xff0c;产生了不同的行为。值得注意的是&#xff0c;虽然多态在功能上与隐藏是类似的&#xff0c;但是还是有较大区别的&#xff0c;本文也会进行多态和隐藏的差异分析。 在继承中要构成多态的条件 1.1必须通过基类的指针或引用…

EIP-712:类型化结构化数据的哈希与签名

1. 引言 以太坊 EIP-712: 类型化结构化数据的哈希与签名&#xff0c;是一种用于对类型化结构化数据&#xff08;而不仅仅是字节串&#xff09;进行哈希和签名 的标准。 其包括&#xff1a; 编码函数正确性的理论框架&#xff0c;类似于 Solidity 结构体并兼容的结构化数据规…

基于S函数的simulink仿真

基于S函数的simulink仿真 S函数可以用计算机语言来描述动态系统。在控制系统设计中&#xff0c;S函数可以用来描述控制算法、自适应算法和模型动力学方程。 S函数中使用文本方式输入公式和方程&#xff0c;适合复杂动态系统的数学描述&#xff0c;并且在仿真过程中可以对仿真…

每日一题洛谷P8664 [蓝桥杯 2018 省 A] 付账问题c++

P8664 [蓝桥杯 2018 省 A] 付账问题 - 洛谷 (luogu.com.cn) 思路&#xff1a;要使方差小&#xff0c;那么钱不能一下付的太多&#xff0c;可以让钱少的全付玩&#xff0c;剩下还需要的钱再让钱多的付&#xff08;把钱少的补上&#xff09;。 将钱排序&#xff0c;遍历一遍&…

迅饶科技X2Modbus网关-GetUser信息泄露漏洞

免责声明&#xff1a;本号提供的网络安全信息仅供参考&#xff0c;不构成专业建议。作者不对任何由于使用本文信息而导致的直接或间接损害承担责任。如涉及侵权&#xff0c;请及时与我联系&#xff0c;我将尽快处理并删除相关内容。 漏洞描述 该漏洞的存在是由于GetUser接口在…

关于inode,dentry结合软链接及硬链接的实验

一、背景 在之前的博客 缺页异常导致的iowait打印出相关文件的绝对路径-CSDN博客 里 2.2.3 一节里&#xff0c;我们讲到了file&#xff0c;fd&#xff0c;inode&#xff0c;dentry&#xff0c;super_block这几个概念&#xff0c;在这篇博客里&#xff0c;我们针对inode和dentr…

PandasAI:当数据分析遇上自然语言处理

数据科学的新范式 在数据爆炸的时代&#xff0c;传统的数据分析工具正面临着前所未有的挑战。数据科学家们常常需要花费70%的时间在数据清洗和探索上&#xff0c;而真正的价值创造时间却被大幅压缩。PandasAI的出现&#xff0c;正在改变这一现状——它将生成式AI的强大能力注入…