Graph 我如何学习Tarjan';s算法?

Graph 我如何学习Tarjan';s算法?,graph,depth-first-search,tarjans-algorithm,Graph,Depth First Search,Tarjans Algorithm,我已经试着从维基百科上学习Tarjan的算法3个小时了,但我就是搞不懂( 为什么它是DFS树的子树?(实际上DFS生成一个林?o_o) 为什么v.lowlink=v.index意味着v是根 有人能给我解释一下/给出这个算法背后的直觉或动机吗?这个想法是:在遍历树时,每次搜索一个分支并进行回溯时,都要检查是否遇到树中“上”节点的边 如果没有(If(v.lowlink=v.index)),则您刚刚完成了一个SCC-它由当前节点和堆栈上的所有节点组成。这正是DFS树的子树,SCC中已完成的节点除外

我已经试着从维基百科上学习Tarjan的算法3个小时了,但我就是搞不懂(

为什么它是DFS树的子树?(实际上DFS生成一个林?o_o) 为什么
v.lowlink=v.index
意味着
v
是根


有人能给我解释一下/给出这个算法背后的直觉或动机吗?

这个想法是:在遍历树时,每次搜索一个分支并进行回溯时,都要检查是否遇到树中“上”节点的边

  • 如果没有(
    If(v.lowlink=v.index)
    ),则您刚刚完成了一个SCC-它由当前节点和堆栈上的所有节点组成。这正是DFS树的子树,SCC中已完成的节点除外

  • 如果这样做,则会将此信息传播到“上”节点(
    v.lowlink:=min(v.lowlink,w.lowlink)
    ),因为边与DFS树中的路径相结合,会创建一个“向上”路径


DFS产生一个森林,但你总是一次考虑一棵树。一个SCC总是包含在一个DFS树中,否则(作为SCC)在两个方向之间都会有一条路径(全部)。有问题的树-这是一个矛盾。

只是补充pjotr的答案:v.lowlink基本上是在树中找到的最上层节点的索引。请记住,在这种情况下,最上层意味着在向下移动时不断增加索引的最小值。在处理完所有后续节点后,基本上有三种情况:

  • v、 lowlink
  • v、 lowlink=v.index:在本例中,我们知道没有后缘引用当前节点上方的任何内容。此节点可能有后缘(这意味着您的后续节点之一w具有一个lowlink,因此w.lowlink=v.lowlink=v.index)。也可能是有一个后缘指向当前节点下的某个对象,这意味着当前节点下有一个已打印出来的强连接组件。但是,当前节点肯定也是强连接组件的根

  • v、 lowlink>v.index:这实际上是不可能的。我只是为了完整起见才列出它


  • 希望有帮助

    关于Tarjan算法的一些直觉:

    • 在DFS期间,当我们遇到来自顶点v的后缘时,我们更新其最低可达祖先,即更新low[v]的值

    • 现在,当处理顶点的所有传出边时,即我们即将退出顶点v的DFS调用,我们将检查low[v]的值,low[v]==v(解释如下)。如果不是,这意味着v不是SCC的根,我们现在将利益给予v的父代,即父代[v]的最低可达祖先现在更改为低[v]

    这听起来很合乎逻辑,好像父[v]到v的祖先没有直接的后缘,但有一条路径(v的后缘+朝向v的边)父[v]仍然可以通过该路径到达v的祖先。 因此,我们也在这里更新了低[parent[v]]。 因此,我们将继续更新此链,所有v的低[v]将继续更新,直到我们到达祖先(通过回溯)。对于这个祖先,低[v]将等于v。因此,这将作为SCC的根源

    希望这有助于掌握桥梁和连接算法
    • 观看视频,获得一种令人敬畏的感觉,即您已经理解了 算法非常好。
    • 从和练习算法
    • 通过练习问题来掌握它:

    很抱歉断开了链接,不知道如何使其工作。请只复制整个链接。断开的链接修复;使用“全球”图标在选定文本上使用特定URL:)这有帮助吗?有时更容易在实际中看到,而不是伪代码,这没有多大帮助。不过谢谢。哦,dfs标签似乎指的是其他东西。我只是无法想象这里的回溯