Tarjan的SCC算法是否给出了SCC的拓扑类型?

时间:2015-09-23 22:25:33

标签: algorithm graph topological-sort tarjans-algorithm

我一直在研究关于它们的SCC和算法,我发现人们几乎总是提到Kosaraju的算法找到SCC并且还以(反向)拓扑排序对它们进行排序

我的问题是:Tarjan的算法还没有找到(反向)拓扑排序吗?我发现它没有被提及(至少从我读过的地方,除了维基百科)。

我一直在思考这个问题并且非常有意义。当在某个节点u上调用tarjans_dfs时,可以在u的SCC之前找到所有可从u访问的SCC。我错了吗?

维基百科说它确实找到了它:

  

"虽然其中的节点顺序没有什么特别之处   每个强连通组件,一个有用的属性   算法是不识别强连通分量   在任何继任者之前。因此,顺序在哪   识别出强烈连接的组件构成反向   拓扑排序由强连接形成的DAG   部件"

这是我的想法,还是更为人所知的是Kosaraju的算法找到了拓扑顺序而不是Tarjan的事实呢?

3 个答案:

答案 0 :(得分:2)

是的,确实如此。 Tarjan的SCC算法通过在图上执行DFS并跟踪堆栈上SCC的根来工作。找到拓扑排序的一种方法是在图上执行DFS并跟踪退出顺序。 Tarjan的SCC算法中这些节点的退出顺序提供了拓扑排序。

在谈到Tarjan的SCC算法时,Donald Knuth甚至提到了in an interview,他说这是他最喜欢的算法之一:

  

他为这个问题设计的数据结构以一种非常漂亮的方式组合在一起,因此在探索有向图时您需要查看的数量总是神奇地触手可及。他的算法也将拓扑排序作为副产品。

答案 1 :(得分:0)

是。由于Tarjan基于深度优先搜索所有你需要做的就是当每个顶点到达"关闭"时,将顶点添加到列表的顶部。 state。(即,它的dfs / tarjan调用以该顶点结束)

这是一个C / C ++ /伪代码示例:

void tarjan(int u) {
    visited[u] = true;
    closed[u] = false;
    //dfs + tarjan processing
    for (vi v = G[u].begin(); v != G[u].end(); v++) {
        if (!visited[*v]) {
            dfs(*v);
        } else if (!closed[*v]) {
            // has Cycle
        }
    }
    closed[u] = true;
    //add u to the top of your list here
}

答案 2 :(得分:-1)

确实如此,我一直在使用它,我想到了同样的问题。

我实际上没有时间来展示它,但每个测试用例(成千上万)总是会返回一个拓扑排序的压缩图。

相关问题