有向图被称为' at-least-one-way-connected '如果,对于图表中的每两个节点u
和v
,请选择u
到v
的路径或v
的路径至u
(或两者)
是否有时间复杂度算法O(m + n)
来解决这个问题?
答案 0 :(得分:5)
为了构建整体解决方案,让我们从这个问题的更简单版本开始。假设您知道输入图是有向无环图(DAG)。在这种情况下你怎么能解决这个问题?好吧,如果DAG有两个不同的源节点,那么它就不可能至少是单向连接(ALOWC),因为它不会是从这些源节点之一到其中一个的路径。其他。如果DAG确实具有单个源节点,则存在从该节点到DAG中的每个其他节点的路径。这意味着如果图中的每一对节点都是ALOWC,则整个图是ALOWC,我们可以通过删除该源节点并递归查看我们剩下的图来确定。换句话说,我们的算法看起来像这样:
while (the graph has more than one node) {
if (the graph has more than one source node) return false;
else find and remove a source node;
}
有效实现此算法的一种方法是首先找到indegree 0的节点。从那里,我们可以从图中删除它并减少每个后继的indegree。然后我们可以看到那些剩下的继承者,这些继承人有0,并从那里开始。这是一些伪代码:
/* Compute indegrees. */
for (each node u) {
u.indegree = 0;
}
for (each edge (u, v) in the graph) {
v.indegree++;
}
/* Find a node with indegree 0. */
Node source = null;
for (each node u in the graph) {
if (u.indegree == 0) {
if (source != null) return false; // Two sources
source = u;
}
}
/* Repeatedly remove the source node, update indegrees, and find the
* next node to process.
*/
while (there is more than one node) {
/* Simulate removing the source node by decrementing the indegree
* of each of its children.
*/
Node next = null;
for (each edge (source, v)) {
v.indegree--;
if (v.indegree == 0) {
if (next != null) return false; // Two sources discovered
next = v;
}
}
source = next;
}
return true;
该算法在时间O(m + n)运行:将计数设置为0需要时间O(n),将时间O(m)初始化为正确值,时间为O(m + n)对于循环,因为每个节点最多被设置为一次源,并且每个边最多访问一次。
所以现在我们有一个算法可以解决DAG的这个问题,但是一般图表呢?好消息是,通过查看图形和图形strongly connected components的condensation,可以将此问题的更一般版本转换为DAG上的问题。 (如果您之前没有看过这些概念,我认为您最好的选择是搜索一下这些概念,因为我不认为我可以在这里给出完整的解释。)
关键见解如下:当且仅当其凝结 ALOWC时,图G才是ALOWC。要知道为什么这样,首先假设冷凝是ALOWC,然后在G中选择任意两个节点u和v。如果u和v强连接,那么从u到v的路径是,所以他们&# 39;重新开始。另一方面,如果u和v没有强连接,那么由于凝结是ALOWC,那么从包含u的SCC到包含v的SCC的路径或者在凝结中反之亦然,那条路径给出原始图G中从u到v(或反之亦然)的路径。
另一方面,如果G是ALOWC,那么如果我们形成它的凝聚,那么得到的DAG必须是ALOWC,因为在DAG中给出了任何两个SCC C1和C2,如果我们在C1和某个节点中选择一个节点u v来自G的C2,然后是从u到v或v到u的路径,因此在缩合中有从C1到C2的路径,反之亦然。
所以这为这个问题提供了一个非常干净的O(m + n)时间算法:
此算法中的每一步都需要时间O(m + n),因此总运行时间也为O(m + n)。
希望这有帮助!