Critical Connections in a Network ( Tarjan Algorithm )

寻找一个图中所有的关键边,关键边的定义是:如果这个边去除,那么所有节点就不能都到达了(不连通)。譬如在上图中,[1, 3]这条边是关键边。

可以使用Tarjan Algorithm来解决这个这个问题:https://www.youtube.com/watch?v=thLQYBlz2DM

基本的思路是,使用两个数组: dic 和 low来分别存储  节点访问的顺序  和 当前节点所有相邻节点中dic最低的节点(不包括direct 父节点)

class Solution:
    def criticalConnections(self, n: int, connections: List[List[int]]) -> List[List[int]]:
        #使用两个数组来保存每个节点的 dic, low(编号, 它能连接的除了根节点的最小节点的编号)
        #首先在dfs的时候让 dic 和 low 都按顺序增长,当所有递归返回时,将low值变为该节点所有的相连节点中 最小的dict值(除了考虑与它相连的根节点)。
        #遍历所有list,check是不是其中一个点的low值大于另一个点的dic值(因为只有没改变过low的节点会发生这种情况)
        map1 = {} #使用一个map来存储边
        for val in connections:
            if map1.get(val[0]) == None:
                map1[val[0]] = [val[1]]
            else:
                map1[val[0]].append(val[1])
            if map1.get(val[1]) == None:
                map1[val[1]] = [val[0]]
            else:
                map1[val[1]].append(val[0])

        dic = [None for _ in range(len(map1.keys()))] #初始化dic
        low = [None for _ in range(len(map1.keys()))] #初始化low
        
        count = 1
        def oneStep(ptr, pre):
            nonlocal count #使用一个全局变量来初始化low 和 dic
            low[ptr] = count
            dic[ptr] = count
            for val in map1[ptr]:#dfs所有没有访问过的相邻节点
                if low[val] == None:
                    count += 1
                    oneStep(val, ptr)
            #After traversing all the nodes, reset the low value to be the lowest one in the adjacent nodes' dic values
            temp = dic[ptr]
            for val in map1[ptr]:
                if pre != None and val != pre: # except the direct father's value
                    temp = min(temp, low[val])
            low[ptr] = temp
        oneStep(0, None)
        print(dic, low)
        #print(dic, low)
        result = []
        for edge in connections:# traverse every edge, if the low[a] > dic[b] or low[b] > dic[b], then this edge is one of the critical edges. 
            a = edge[0]
            b = edge[1]
            if low[a] > dic[b] or low[b] > dic[a] :
                result.append([a, b])
        return result

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值