按照tarjan寻找强连通分量的模板,稍微改一下。
先回顾一下强连通分量,首先维护dnf和low两个列表,dnf【i】表示第i个节点的编号,low【i】表示第i个节点能到达的最小节点编号。例如节点0可以到1,节点1能到达2,节点2能到达0,那么可以推出low【1】= 0。
强联通是有向图,而边双连通是无向的,那么如果某次到达了v节点,不能让他再顺着原路返回父节点u,否则low【v】肯定等于low【u】,总结就是从u节点到达v后,不能再从v到达u。
题目需要找到这个关键链接,就是找到两个点之间只存在一条边的这两个节点。
如果low【v】= dnf【v】,说明节点v不能到达v的父节点u及之前的其他节点,就是说u到v只有一条边。
python
class Solution:
def criticalConnections(self, n: int, connections: List[List[int]]) -> List[List[int]]:
dnf = [0] * n
low = [0] * n
edge = defaultdict(list)
ans = []
idx = 1
stack = []
for x, y in connections:
edge[x].append(y)
edge[y].append(x)
def tj(u, v):
# u is father
# v is son
nonlocal idx
dnf[v], low[v] = idx, idx
idx += 1
for nex in edge[v]:
if dnf[nex] == 0:
tj(v, nex)
low[v] = min(low[v], low[nex])
elif nex != u:
low[v] = min(low[v], low[nex])
if low[v] == dnf[v] and u != v:
ans.append([u,v])
tj(0, 0)
return ans