问题描述
尝试通过directed graph
在DFS
中查找所有个周期。但是有一个问题。
问题
当2个节点之间存在多个循环时,有时只能检测到最长的一个,而跳过较短的一个。
这是由于访问节点时,我将跳过它,因此跳过了较短的周期。 但是,如果我不跳过访问的节点,则DFS搜索将永远重复。
示例
图:
1 -> [2,4]
2 -> [3]
3 -> [4]
4 -> [1]
1
和4
之间有2个周期:
- (A) 1-> 2-> 3-> 4-> 1
- (B) 1-> 4-> 1
如果首先检测到A,则无法检测到周期B,因为4
由于被访问而将被跳过,并且永远不会返回到1。
当前想法
- 一个可能的解决方案是从每个节点开始,即使它已经被访问过。但是我想要一个更好的解决方案。
- 计算并记住路径的哈希,仅当存在相同哈希时才跳过吗?那会需要一些记忆,对吗?而且,仍然存在2个具有相同哈希值的不同路径通向相同节点的可能性,这不能完全解决问题。
有什么主意吗?
解决方法
积分:https://www.hackerearth.com/practice/notes/finding-all-elementry-cycles-in-a-directed-graph/
integer list array A(n);logical array marked(n);integer stack current_stack ;integer stack marked_stack;/* A(n) is the array of list wich is adjacency list representation*/
integer procedure intialize(); /*initialize the values*/
begin;
for i in n do
marked(i):=false
integer procedure print_cycles();
begin
for i in current_stack do
print i ;
logical procedure backtrack(k) do
begin
logical flag=false;
current_stack->push(k);
marked_stack->push(k);
marked(n):=true;
for i in A(k) do
if i < s; /* To find only disticnt cycles in topological manner*/
delete A(i);
if i==s; /Cycle found */
print_cycles()
if marked(i):= false;
backtrack(n); /*continue dfs*/
if flag :=true;
for i in marked_stack do /*unmark the elements that have been visited in any of the cycles starting from s*/
marked(i):=false;
current_stack->pop(k);
backtrack:=flag
end backtrack(k)
begin
integer procedure backtrack_Util();
begin
for s in n do
backtrack(s);
while marked_stack(s)->empty do
for i in marked_stack do
marked(i):=false
end backtrack_Util()
我们想找到不同的周期。因此,我们需要按一定顺序访问顶点。按照该顺序,我们需要找到从该顶点开始的循环,并且该循环中不应包含该顺序中起始顶点之前的任何顶点。如何获得该订单?上述评论之一中的topological manner
一词与topological sort
不明确,事实并非如此。我认为我们可以选择像顶点数字一样简单的排序,例如0,1,2,..,v。让我们说我们希望找到一个从2开始的循环。为了避免发现重复的循环,我们将不使用顶点0和1。如果有任何循环包含从2到1或2到0的边,查找从0或1开始的循环时已经考虑过。
让我介绍一个具体的参考资料,它将帮助您完成任务。它是Johnson's algorithm。显然,这是完成任务的最快方法。
在第3页上,它提到:
为避免电路重复,添加顶点v时将其阻塞 到以s开头的一些基本路径。只要它保持阻塞状态 从v到s的每个路径都与当前基本路径在a处相交 s以外的其他顶点。此外,顶点不会成为根 用于构造基本路径的顶点,除非它是最小顶点 在至少一个基本电路中。
您也可以观看this youtube video,以了解更多信息。
我认为这些信息是可以接受的。