首页 > 其他分享 >Leetcode 1192. 查找集群内的关键连接

Leetcode 1192. 查找集群内的关键连接

时间:2024-10-12 12:44:57浏览次数:1  
标签:node graph self 1192 List 节点 查找 服务器 Leetcode

1.题目基本信息

1.1.题目描述

力扣数据中心有 n 台服务器,分别按从 0 到 n-1 的方式进行了编号。它们之间以 服务器到服务器 的形式相互连接组成了一个内部集群,连接是无向的。用 connections 表示集群网络,connections[i] = [a, b] 表示服务器 a 和 b 之间形成连接。任何服务器都可以直接或者间接地通过网络到达任何其他服务器。

关键连接 是在该集群中的重要连接,假如我们将它移除,便会导致某些服务器无法访问其他服务器。

请你以任意顺序返回该集群内的所有 关键连接 。

1.2.题目地址

https://leetcode.cn/problems/critical-connections-in-a-network/description/

2.解题方法

2.1.解题思路

tarjan计算无向图中桥的个数

2.2.解题步骤

构建tarjan算法的模板,构建图graph,然后获取桥即可,详情请看代码中的注释。

3.解题代码

Python代码

from typing import List
# ==> 无向图的Tarjan算法模板,参数为邻接表,可以获取割点状态、桥、各节点的当前时间戳和子孙节点最小时间戳
class UndirectedGraphTarjan():
    def __init__(self,graph:List[List[int]]):
        self.graph=graph
        self.length=len(self.graph)
        self.dfn=[-1]*self.length   # dfn为各个节点的访问时间戳
        self.low=[-1]*self.length   # low为各个节点的子孙节点中最小时间戳
        self.cutPoint=[False]*self.length   # 各个节点的割点状态
        self.bridges=[]
        self.timestamp=0    # 时间戳,初始化为0,且保证唯一
    
    # tarjanDfs任务:设置node节点的访问时间戳、子孙节点最小访问时间戳、node的割点状态
    def tarjanDfs(self,node:int,father:int):
        # 注意:割点和桥针对无向图,如果图是有向的,则考虑算强连通算法的个数即可(算low中相同的个数即可)
        # 割点条件:条件1:节点node非root+有儿子,同时dfn(node)<=low(node) / 条件2:节点node是root+非连通儿子节点数大于等于2
        # 桥的条件:dfn(node)<low(child)
        # 标记当前节点的访问时间戳并初始化子孙节点中最小的访问时间戳
        self.dfn[node]=self.timestamp
        self.low[node]=self.timestamp
        self.timestamp+=1
        childCnt=0
        for child in self.graph[node]:
            # 如果子节点等于父节点,跳过,否则反复执行father的dfs任务,造成错误
            if child!=father:
                # 如果孩子节点没有访问过
                if self.dfn[child]==-1:
                    childCnt+=1
                    self.tarjanDfs(child,node)  # 设立设置子节点的dfn、low、割点状态
                    # 割点条件1
                    if father!=-1 and self.dfn[node]<=self.low[child] and not self.cutPoint[node]:
                        self.cutPoint[node]=True
                    # 桥的条件
                    if self.dfn[node]<self.low[child]:
                        self.bridges.append([node,child])
                # 设置node节点的子孙节点中的最小时间戳
                self.low[node]=min(self.low[node],self.low[child])
            # 割点条件2
            if father==-1 and childCnt>=2 and not self.cutPoint[node]:
                self.low[node]=True

class Solution:
    def criticalConnections(self, n: int, connections: List[List[int]]) -> List[List[int]]:
        # 构建图
        graph=[[] for _ in range(n)]
        for x,y in connections:
            graph[x].append(y)
            graph[y].append(x)
        # targen算法获取无向图的桥
        ugTarjan=UndirectedGraphTarjan(graph)
        ugTarjan.tarjanDfs(0,-1)
        return ugTarjan.bridges

4.执行结果

在这里插入图片描述

标签:node,graph,self,1192,List,节点,查找,服务器,Leetcode
From: https://www.cnblogs.com/geek0070/p/18460284

相关文章

  • LeetCode题练习与总结:单词规律--290
    一、题目描述给定一种规律 pattern 和一个字符串 s ,判断 s 是否遵循相同的规律。这里的 遵循 指完全匹配,例如, pattern 里的每个字母和字符串 s 中的每个非空单词之间存在着双向连接的对应规律。示例1:输入:pattern="abba",s="dogcatcatdog"输出:tr......
  • 代码随想录Day23 | LeetCode 455. 分发饼干、LeetCode 53. 最大子数组和、LeetCode 37
    LeetCode455.分发饼干贪心就是干classSolution:deffindContentChildren(self,g:List[int],s:List[int])->int:g.sort(reverse=True)s.sort(reverse=True)i=j=0res=0whilei<len(g)andj<len(......
  • LeetCode:871. 最低加油次数(DP Java)
    目录871.最低加油次数题目描述:实现代码与解析:DP原理思路:871.最低加油次数题目描述:        汽车从起点出发驶向目的地,该目的地位于出发位置东面 target 英里处。沿途有加油站,用数组 stations 表示。其中 stations[i]=[positioni,fueli] 表示第 ......
  • Leetcode 839. 相似字符串组【附并查集模板】
    1.题目基本信息1.1.题目描述如果交换字符串X中的两个不同位置的字母,使得它和字符串Y相等,那么称X和Y两个字符串相似。如果这两个字符串本身是相等的,那它们也是相似的。例如,”tars”和“rats”是相似的(交换0与2的位置);“rats”和“arts”也是相似的,但是“s......
  • c++map 查找元素和list查找元素速度对比
    在C++中,std::map和std::list是两种不同的容器类型,前者是基于红黑树实现的关联容器,后者是双向链表。如果你想比较这两种容器在查找元素上的速度,通常std::map会比std::list快得多。因为std::map的查找操作是平均常数时间复杂度,即O(logn),而std::list的查找操作是线性时间复杂度,即O(......
  • 322. 零钱兑换(最短路做法leetcode)
    322.零钱兑换classSolution{publicintcoinChange(int[]coins,intamount){//使用图的方式解决//最短路问题,总金额从0到amount需要走多少步//每一步能迈向的点都是面额里的点+出发点//每步的边权都是1,重要的是走到amount......
  • 深度理解二分查找思想~
    二分思想的基本思想:是将有序数组分成两半,通过比较数组中间元素与目标值大小,来决定下一步搜索的区间是左半部分还是右半部分,然后递归再选定的区间内继续查找。(部分有序的数组也可使用这一思想)二分查找基础代码根据划分区间方法的不同,主要分为三种类型(并在代码后方附有......
  • Leetcode 864. 获取所有钥匙的最短路径
    1.题目基本信息1.1.题目描述给定一个二维网格grid,其中:‘.’代表一个空房间‘#’代表一堵墙‘@’是起点小写字母代表钥匙大写字母代表锁我们从起点开始出发,一次移动是指向四个基本方向之一行走一个单位空间。我们不能在网格外面行走,也无法穿过一堵墙。如果途经一个......
  • arm imx6ull docker启动失败问题查找与解决 内核配置相关
    1、增加POSIXMessageqeue:couldnotgetinitialnamespace:nosuchfileordirectory CONFIG_POSIX_MQUEUE=y2、增加namespacefailedtosettoinitialnamespaceCONFIG_NAMESPACES=y3、创建网络失败,veth配置:dockercreateendpointquirky_shternonnetworkbridge......
  • (LeetCode 热题 100) 1143. 最长公共子序列(动态规划dp)
    题目:1143.最长公共子序列思路:经典动态规划dp题型,时间复杂度为0(n^2)。C++版本:classSolution{public:intlongestCommonSubsequence(stringtext1,stringtext2){intn=text1.size(),m=text2.size();//状态f[i][j]表示:text1[0,i]和text2[0......