Def:桥是一条边,当移除时,将断开图形(或将连接的组件数量增加 1)。
关于图中桥梁的一项观察;属于循环的边都不能是桥。所以在一个图表中,例如A--B--C--A
,删除任何边缘A--B
, B--C
and C--A
不会断开图表。但是,对于无向图,边A--B
暗示B--A
;这条边仍然可以是一座桥,它所在的唯一循环是A--B--A
。因此,我们应该只考虑由后沿形成的那些环。这就是您在函数参数中传递的父信息的用处。它将帮助您不使用诸如A--B--A
.
现在要识别后边缘(或环),A--B--C--A
我们使用low
and pre
数组。数组pre
就像visited
dfs算法中的数组;但我们不是仅仅将顶点标记为已访问,而是用不同的编号(根据其在 dfs 树中的位置)来标识每个顶点。这low
数组有助于识别是否存在循环。这low
数组标识最低编号(从pre
array) 当前顶点可以到达的顶点。
让我们看一下这张图A--B--C--D--B
.
从A开始
dfs: ^ ^ ^ ^ ^
pre: 0 -1 -1 -1 -1 0--1 -1 -1 1 0--1--2 -1 1 0--1--2--3 1 0--1--2--3--1
graph: A--B--C--D--B A--B--C--D--B A--B--C--D--B A--B--C--D--B A--B--C--D--B
low: 0 -1 -1 -1 -1 0--1 -1 -1 1 0--1--2 -1 1 0--1--2--3 1 0--1--2--3->1
此时,您已经遇到了图中的循环/循环。在你的代码中if (pre[w] == -1)
这次将会是假的。因此,您将输入 else 部分。 if 语句检查 ifB
是 的父顶点D
。不是这样D
会吸收B
's pre
值转化为low
。继续这个例子,
dfs: ^
pre: 0--1--2--3
graph: A--B--C--D
low: 0--1--2--1
This low
的价值D
传播回C
通过代码low[v] = Math.min(low[v], low[w]);
.
dfs: ^ ^ ^
pre: 0--1--2--3--1 0--1--2--3--1 0--1--2--3--1
graph: A--B--C--D--B A--B--C--D--B A--B--C--D--B
low: 0--1--1--1--1 0--1--1--1--1 0--1--1--1--1
现在,循环/循环已确定,我们注意到顶点A
不是循环的一部分。所以,你打印出A--B
作为一座桥梁。代码low['B'] == pre['B']
意味着边缘B
将是一座桥梁。这是因为,我们可以到达的最低顶点B
is B
本身。
希望这个解释有帮助。