|
| 1 | +# Source: https://tinyurl.com/yc2tzb4k |
| 2 | +import collections |
| 3 | + |
| 4 | + |
| 5 | +class Solution(object): |
| 6 | + def criticalConnections(self, n, connections): |
| 7 | + """ |
| 8 | + :type n: int |
| 9 | + :type connections: List[List[int]] |
| 10 | + :rtype: List[List[int]] |
| 11 | + """ |
| 12 | + graph = defaultdict(list) |
| 13 | + for connection in connections: |
| 14 | + x, y = connection |
| 15 | + graph[x].append(y) |
| 16 | + graph[y].append(x) |
| 17 | + |
| 18 | + criticalConnections = set(map(tuple, map(sorted, connections))) |
| 19 | + serverRank = [-2] * n |
| 20 | + self.dfsServerSearch(0, 0, graph, serverRank, criticalConnections, |
| 21 | + n) # since this is a connected graph, we don't have to loop over all nodes. |
| 22 | + return list(criticalConnections) |
| 23 | + |
| 24 | + def dfsServerSearch(self, serverNode, depth, graph, serverRank, criticalConnections, n): |
| 25 | + if serverRank[serverNode] >= 0: |
| 26 | + return serverRank[serverNode] # # visiting (0<=serverRank<n), or visited (serverRank=n) |
| 27 | + serverRank[serverNode] = depth |
| 28 | + minBackDepth = n |
| 29 | + for neighbour in graph[serverNode]: |
| 30 | + if serverRank[neighbour] == depth - 1: |
| 31 | + continue # don't immmediately go back to parent. that's why i didn't choose -1 as the special value, in case depth==0. |
| 32 | + backDepth = self.dfsServerSearch(neighbour, depth + 1, graph, serverRank, criticalConnections, n) |
| 33 | + if backDepth <= depth: |
| 34 | + criticalConnections.discard(tuple(sorted((serverNode, neighbour)))) |
| 35 | + minBackDepth = min(minBackDepth, backDepth) |
| 36 | + return minBackDepth |
0 commit comments