给定一般的无向图,我们如何在O(N + M)时间内打印图的所有双连通分量?我知道Tarjan的算法用于输出无向图的所有关节点,但我发现很难扩展算法来打印双连通组件。我尝试搜索谷歌,但我得到的所有结果都不适用于我的测试用例,因为他们错过了算法的边缘情况。
有人可以提供此问题的工作代码。
Def:双连通组件是一个连接的子图,不包含顶点,删除会断开子图。
编辑:我已成功实施了Niklas提供的this link中所述的算法。现在我有一个不同的问题,我怎样才能找到一个无向图的子图,其中没有边删除会断开子图。请帮我解决这个替代问题。
答案 0 :(得分:6)
这是一个classical problem with a known linear-time algorithm。但是,您可能需要先将图形分解为连接的组件。来自维基百科的算法描述:
用于计算双连通组件的经典顺序算法 在约翰霍普克罗夫特和罗伯特的连通无向图中 Tarjan(1973)[1]以线性时间运行,并且基于深度优先 搜索。该算法也概述为引言的问题22-2 算法(第2版和第3版)。这个想法是运行一个 深度优先搜索,同时保留以下信息: 深度优先搜索树中每个顶点的深度(一旦获得) 访问),并为每个顶点v,所有的邻居的最低深度 深度优先搜索树中v的后代,称为 该lowpoint。深度是在深度优先期间保持的标准 搜索。访问所有后,可以计算v的低点 v的后代(即,在v弹出之前) 深度优先搜索堆栈)作为深度v的最小值,深度 v的所有邻居(除了v的父亲之外) 深度优先搜索树)和所有v的孩子的低点 深度优先搜索树。关键的事实是非根顶点v是a 切割顶点(或铰接点)分开两个双连体 组件当且仅当存在v的子y时 低点(y)≥深度(v)。这个属性可以测试一次 从v的每个孩子返回的深度优先搜索(即,只是 在v从深度优先搜索堆栈中弹出之前,如果 true,v将图形分成不同的双连通组件。 这可以通过计算一个双连通组件来表示 每个这样的y(包含y的组件将包含子树 y,加上v),然后从树中删除y的子树 根顶点必须单独处理:它只是一个切割顶点 如果它至少有两个孩子。因此,只需构建一个就足够了 根的每个子树的子组件(包括根)。
可以在http://www.cs.umd.edu/class/fall2005/cmsc451/biconcomps.pdf找到一个好的伪代码实现。
答案 1 :(得分:3)
在Planarity Testing by Path Addition上查看这篇博士论文。
Chapter 5给出DFS算法的伪代码(使用递归或迭代的两个版本)和用于将DFS树(也称为Tremaux树)分区(分解)为路径段层次结构的算法(或链)。 Chapter 4根据路径段尾部在DFS树中的相对位置(相对于路径段的头部),将这些路径段分为4种不同的类型。
鉴于这种分离,您可以将树分区为双连通组件,以便:
如果操作正确,您应该能够在O(V + E)时间内提取这些双连通组件。
论文后面有Java源代码,它在O(V + E)时间和时间进行全面平面度测试。内存可能会给你一些进一步的指针(并提取O(P(V + E))中双连通分量嵌入的所有排列P。)