当前位置: 首页 > article >正文

代码随想录算法训练营第五十五天 | 寻找存在的路径

目录

寻找存在的路径

思路

方法一: 并查集-卡哥

方法二:并查集


寻找存在的路径

  • 题目链接:卡码网题目链接(ACM模式)
  • 文章讲解:代码随想录 

给定一个包含 n 个节点的无向图中,节点编号从 1 到 n (含 1 和 n )。

你的任务是判断是否有一条从节点 source 出发到节点 destination 的路径存在。

输入描述

第一行包含两个正整数 N 和 M,N 代表节点的个数,M 代表边的个数。

后续 M 行,每行两个正整数 s 和 t,代表从节点 s 与节点 t 之间有一条边。

最后一行包含两个正整数,代表起始节点 source 和目标节点 destination。

输出描述

输出一个整数,代表是否存在从节点 source 到节点 destination 的路径。如果存在,输出 1;否则,输出 0。

输入示例

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

输出示例

1

提示信息

数据范围:

1 <= M, N <= 100。

思路

本题是并查集基础题目。 如果还不了解并查集,可以看这里:并查集理论基础(opens new window)

并查集可以解决什么问题呢?

主要就是集合问题,两个节点在不在一个集合,也可以将两个节点添加到一个集合中

这里整理出我的并查集模板如下:

n = 1005 # n根据题目中节点数量而定,一般比节点数量大一点就好


# 并查集初始化
father = list(range(n + 1))
# 并查集里寻根的过程
def find(u) :
    if father[u] != u:
            father[u] = find(father[u])  # 路径压缩
        return father[u]

# 判断 u 和 v是否找到同一个根
def isSame(u, v) :
    u = find(u)
    v = find(v)
    return u == v


# 将v->u 这条边加入并查集
def join(u, v) :
    u = find(u) # 寻找u的根
    v = find(v) # 寻找v的根
    if (u == v) : return # 如果发现根相同,则说明在一个集合,不用两个节点相连直接返回
    father[v] = u

以上模板中,只要修改 n 大小就可以。

并查集主要有三个功能:

  1. 寻找根节点,函数:find(int u),也就是判断这个节点的祖先节点是哪个
  2. 将两个节点接入到同一个集合,函数:join(int u, int v),将两个节点连在同一个根节点上
  3. 判断两个节点是否在同一个集合,函数:isSame(int u, int v),就是判断两个节点是不是同一个根节点

简单介绍并查集之后,我们再来看一下这道题目。

为什么说这道题目是并查集基础题目,题目中各个点是双向图链接,那么判断 一个顶点到另一个顶点有没有有效路径其实就是看这两个顶点是否在同一个集合里。

如何算是同一个集合呢,有边连在一起,就算是一个集合。

此时我们就可以直接套用并查集模板。

使用 join(int u, int v)将每条边加入到并查集。

最后 isSame(int u, int v) 判断是否是同一个根 就可以了。

方法一: 并查集-卡哥

class UnionFind:
    def __init__(self, size):
        self.parent = list(range(size + 1))  # 初始化并查集

    def find(self, u):
        if self.parent[u] != u:
            self.parent[u] = self.find(self.parent[u])  # 路径压缩
        return self.parent[u]

    def union(self, u, v):
        root_u = self.find(u)
        root_v = self.find(v)
        if root_u != root_v:
            self.parent[root_v] = root_u

    def is_same(self, u, v):
        return self.find(u) == self.find(v)


def main():
    import sys
    input = sys.stdin.read
    data = input().split()
    
    index = 0
    n = int(data[index])
    index += 1
    m = int(data[index])
    index += 1
    
    uf = UnionFind(n)
    
    for _ in range(m):
        s = int(data[index])
        index += 1
        t = int(data[index])
        index += 1
        uf.union(s, t)
    
    source = int(data[index])
    index += 1
    destination = int(data[index])
    
    if uf.is_same(source, destination):
        print(1)
    else:
        print(0)

if __name__ == "__main__":
    main()

方法二:并查集

class Solution:
    def __init__(self) -> None:
        self.father = []

    def graph(self,n):
        for i in range(n):
            self.father.append(i)

    def is_Same(self,source,destination):
        source = self.find(source)
        destination = self.find(destination)
        return source == destination
    
    def find(self,ele):
        # # 写法一
        # if ele == self.father[ele]:
        #     return ele
        # else:
        #     self.father[ele] = self.find(self.father[ele])
        #     return self.father[ele]

        # 写法二

        if ele != self.father[ele]:
            self.father[ele] = self.find(self.father[ele])

        return self.father[ele]
    
    def join(self,u,v):
        u = self.find(u)
        v = self.find(v)

        if u != v:
            self.father[v] = u

def main():
    n,m = map(int,input().split())
    g = Solution()
    g.graph(n+1)

    for i in range(m):
        u,v = map(int,input().split())
        g.join(u,v)

    source,destination = map(int,input().split())

    print(1) if g.is_Same(source,destination) else print(0)

if __name__=="__main__":
    main()


http://www.kler.cn/a/299457.html

相关文章:

  • AI-System 学习
  • 如何写美赛(MCM/ICM)论文中的Summary部分
  • 合并2个排序的链表
  • python学opencv|读取图像(四十七)使用cv2.bitwise_not()函数实现图像按位取反运算
  • 机器学习2 (笔记)(朴素贝叶斯,集成学习,KNN和matlab运用)
  • 【深度分析】DeepSeek 遭暴力破解,攻击 IP 均来自美国,造成影响有多大?有哪些好的防御措施?
  • CAN集线器(工业级、隔离式)
  • Filebeat、Logstash和Fluentbit -- Kafka
  • Python 中的模块
  • ubuntu 和windows用samba服务器实现数据传输
  • Linux基础环境搭建(CentOS7)- 虚拟机准备_搭建hadoop能使用桥接模式吗
  • 【机器学习】4 ——熵
  • K8S - Emptydir - 取代ELK 使用fluentd 构建logging saidcar
  • 3.无人机介绍
  • 携手浙商证券、华锐技术,共话交易技术的创新与应用
  • 论文翻译:arxiv-2024 Benchmark Data Contamination of Large Language Models: A Survey
  • 【南京工业大学主办,JPCS出版】自动化、电气控制系统与设备
  • Linux线程管理进阶:分离,等待、终止与C++11线程接口的封装实践
  • LeetCode - 16 最接近的三数之和
  • C++通过返回值和引用参数赋值局部变量有什么区别,有什么风险
  • Redis学习——List的连锁更新如何解决?ListPack算法如何改变?
  • python测试开发---vue基础
  • C++设计模式——Mediator中介者模式
  • python-游戏自动化(二)(OpenCV图像运用基础)
  • 通信工程学习:什么是IP-CAN(IP连接接入网)
  • 【鸿蒙应用开发】常见的容器组件:ColumnSplit、RowSplit和Flex