【发布时间】:2014-06-14 05:19:49
【问题描述】:
我正在寻找最简单的算法,它可以判断(返回真或假)在给定有向图的情况下顶点 v 和 t 之间是否存在非简单路径。
我不介意使用 BFS、DFS、Dijkstra 或任何其他有助于解决此问题的算法,我试图获取 SCC 图,但找不到任何用处。
任何帮助将不胜感激!
谢谢!
【问题讨论】:
标签: algorithm graph computer-science graph-algorithm depth-first-search
我正在寻找最简单的算法,它可以判断(返回真或假)在给定有向图的情况下顶点 v 和 t 之间是否存在非简单路径。
我不介意使用 BFS、DFS、Dijkstra 或任何其他有助于解决此问题的算法,我试图获取 SCC 图,但找不到任何用处。
任何帮助将不胜感激!
谢谢!
【问题讨论】:
标签: algorithm graph computer-science graph-algorithm depth-first-search
Step 0: 如果没有从 v 到 t 的路径,那么答案是否定的。
Step 1: 将 G 的所有强连通分量折叠后生成图 G'。
Step 2: 如果顶点'v'是某个由多个顶点组成的SCC的一部分,那么肯定存在非简单路径。同样,如果顶点 't' 是由超过 1 个顶点组成的某个 SCC 的一部分,则答案为“是”。
Step 3: 如果 step2 不正确。然后确定图 G' 中是否存在从 v 到 t 的任何路径,该路径通过一个顶点,该顶点被折叠成 2 个或更多顶点的强连通分量。如果是,那么答案是肯定的,否则答案是否定的。
运行时间:上述算法中每个步骤的 O(M+N)。因此总体O(M+N)。
编辑:关于如何在线性时间内执行第 3 步:
对于 G' 中的每个顶点,维护两件事:
现在,如果存在从 G' 中的顶点 'vertex' 到通过任何大小 >= 2 的 SCC 顶点的顶点 t 的路径,则以下函数 throughSCC(int vertex) 将返回 true。该函数的伪代码:
boolean throughSCC(int vertex){
if(!reachable[vertex]){
return false;
}
if(sz[vertex] >= 2){
return true;
}
for(all neighbours X of vertex){
if(throughSCC(X)){
return true;
}
}
return false;
}
【讨论】:
由于 SCC 算法有点烦人,这里有一个替代算法。遍历一次以确定哪些顶点可以从 v 到达。从 t 向后遍历,忽略从 v 无法到达的顶点,寻找一个循环。如果找到这样的循环,则报告存在非简单路径。
【讨论】: