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

算法 之 求解有向图和无向图的环的长度

文章目录

  • 习题
    • 2608.图中最短环
    • 2360.图中的最长环

  • 求解一个图中的,环的长度是一类比较经典的问题,当然判断是否有环就是更加基础一点的问题啦

  • 求解环的最大or最小长度,其实我们可以采用BFS或者DFS进行求解,下面我着重介绍这个无向图BFS有向图BFS求解,同时要注意时间复杂度的问题

  • 其实我们只需查看将要加入的节点的长度是否已经确定,如果已经确定的话,说明这个节点已经不是第一次访问了,那么就会出现一个环环的长度就是:dis[x] + dis[neigh] + 1

  • 无向图中,需要遍历每一个起点的情况,并且还不能在找到第一个环就返回

在这里插入图片描述

习题

2608.图中最短环

2608.图中最短环

在这里插入图片描述
在这里插入图片描述

  • 无向图的情况,需要遍历每一个起点
  • 观察时间复杂度,每次的bfs都是o(m),每一个节点都遍历,那就是 o(n*m)

from collections import deque

class Solution:
    def findShortestCycle(self, n: int, edges: List[List[int]]) -> int:
        graph = [[] for _ in range(n)]
        for u, v in edges:
            graph[u].append(v)
            graph[v].append(u)
        
        min_cycle = float('inf')

        def bfs(start):
            queue = deque([(start, -1)])  # (node, parent)
            visited = {start: 0}  # 记录节点到start的距离
            ans = float("inf")
            while queue:
                x, fa = queue.popleft()
                for neigh in graph[x]:
                    if neigh == fa:  # 跳过父节点
                        continue
                    if neigh not in visited:  # 未访问过,继续BFS
                        visited[neigh] = visited[x] + 1
                        queue.append((neigh, x))
                    else:  # 发现环!
                        # 环长度 = x到start的距离 + neigh到start的距离 + 1
                        cycle_len = visited[x] + visited[neigh] + 1
                        ans = min(ans,cycle_len)
            return ans

            return float('inf')  # 未找到环

        for i in range(n):
            cycle_len = bfs(i)
            print(cycle_len)
            min_cycle = min(min_cycle, cycle_len)
        
        return min_cycle if min_cycle != float('inf') else -1

2360.图中的最长环

2360.图中的最长环

在这里插入图片描述
在这里插入图片描述

  • 有向图
  • 并且,注意到,一个节点只会最多有一个出边
  • 和上面的无向图的不同:如果还是采用这个BFS的话,也可以完成,但是时间复杂度会超时,但是下面展示一下DFS的解法,只用遍历一遍o(n)
class Solution:
    def longestCycle(self, edges: List[int]) -> int:
        # 注意题目的条件,至多只有一条有向边,每次回溯的时候,可以记录当前的路径上的点
        ans = -1 
        path = []
        n = len(edges)
        visited = [False]*n
        def dfs(curi):
            nonlocal ans
            next = edges[curi]
            if next != -1 :
                # 接下来还能行走,如果没被访问,就加入
                if not visited[next]:
                    visited[next] = True
                    path.append(next)
                    dfs(next)
                else:
                    # 被访问过了,需要判断是否在路径中
                    if next in path:
                        cal = path.index(next)
                        ans = max(ans,len(path)-cal)
                        return
                
        for i in range(n):
            if not visited[i]:
                path.clear()
                path.append(i)
                dfs(i)
        return ans

http://www.dtcms.com/a/99725.html

相关文章:

  • CSS学习笔记4——盒子模型
  • IO模型之于并发编程模型、并发模型之于架构模式
  • 破界·共生:生成式人工智能(GAI)认证重构普通人的AI进化图谱
  • SpringCould微服务架构之Docker(6)
  • 【C#】C#字符串拼接的6种方式及其性能分析对比
  • Axure项目实战:智慧运输平台后台管理端-货主管理(中继器)
  • 21 python __name__ 与 __main__
  • Java中的String类
  • 智能巡检机器人:2025年企业安全运维的“数字哨兵“
  • Vue 3 中 slot插槽的使用方法
  • 最大子序和 买股票的最佳时机|| 跳跃游戏
  • 【计算机网络】深入解析TCP/IP参考模型:从四层架构到数据封装,全面对比OSI
  • 面经-项目
  • 革新测试管理 2.0丨Storm UTP统一测试管理平台智能化升级与全流程优化
  • HCIP之VRRP
  • 晶晨S905L3A(B)-安卓9.0-开启ADB和ROOT-支持IPTV6-支持外置游戏系统-支持多种无线芯片-支持救砖-完美通刷线刷固件包
  • memtest86检测内存
  • Anaconda Jupyter 默认启动位置修改
  • 矩阵中对角线的遍历问题【C++】
  • JavaScript运算符与逻辑中断
  • 从零到前沿:2025年人工智能系统性学习路径与最新技术融合指南
  • LangChain 基础系列之文档加载与分割详解:从非结构化数据到知识图谱的关键一步
  • ubuntu24 部署vnc server 使用VNC Viewer连接
  • vLLM 实现加速的原理及举例; vLLM 与 TensorRT 的区别
  • C#里使用C#语言作为脚本运行的方法
  • HarmonyOS NEXT——鸿蒙神策埋点(二)
  • 了解遗传算法的Matlab程序的奥妙之处
  • 【记录自己第一个github 100星项目】采用flask框架构建一个前端页面,进行OpenManus的调用,对OpenManus生成的文件进行预览。
  • 使用Python的pytesseract进行网站模拟登录的脚本,主要针对古诗文网(gushiwen.cn)的登录功能。
  • 第十四届蓝桥杯真题(PWM输出)