Algorithm 在压缩有向图中检测循环?

Algorithm 在压缩有向图中检测循环?,algorithm,data-structures,graph-theory,Algorithm,Data Structures,Graph Theory,我正在为考试而学习,无法解决这个问题: 给出了一个n3->4->1的图 对于此输入: 4.4 1 2 3 14 2 3 4 3 4 4 答案是否定的 所以主要的问题是,这个图可能非常大,我无法创建它并运行DFS。它必须做得更快。我的第一个想法是使用拓扑排序算法。如果它起作用,那么给定的图中就没有循环,否则就有循环。但是很难更新节点的度(以便在该算法的每个步骤中选择deg_in=0的节点)。我在想也许使用区间树会有所帮助-当我删除节点v时,我可以看到他的邻接列表(该列表的元素将被赋予区间),并且对

我正在为考试而学习,无法解决这个问题:

给出了一个n3->4->1的图

对于此输入:

4.4

1 2 3

14

2 3 4

3 4 4

答案是否定的

所以主要的问题是,这个图可能非常大,我无法创建它并运行DFS。它必须做得更快。我的第一个想法是使用拓扑排序算法。如果它起作用,那么给定的图中就没有循环,否则就有循环。但是很难更新节点的度(以便在该算法的每个步骤中选择deg_in=0的节点)。我在想也许使用区间树会有所帮助-当我删除节点v时,我可以看到他的邻接列表(该列表的元素将被赋予区间),并且对于所有区间,这些点的度数都会减少。因此,我可以在对数时间内检查某个节点的度数,但仍然无法快速更新deg_in=0的节点列表。我不知道,也许我正在尝试一个无法修复的解决方案


有人能帮忙吗?

我将尝试为算法编写一个元代码。这将是图移动算法的一个特例。其特点是生产线的包装储存

// Outer loop to check all nodes
CheckedNodes = (empty)
for n1 in 1 .. n {
    if (not(CheckedNodes contains n1)) {
        add n1 to CheckedNodes
        VisitedNodes = (empty) // initialization
        VisitableNodes = { n1 } // start the walk from here
        // Inner loop to walk through VisitableNodes
        While (VisitableNodes is not empty) {
            n2 := select one from VisitableNodes
            remove n2 from VisitableNodes
            add n2 to CheckedNodes // this will stop processing again
            for all lines starting from n2 { // we add all points for all lines
                for n3 in line.start .. line.end { 
                    if (VisitedNodes contains n3) { 
                        // we found an already visited node
                        return "Circle found in Graph!" 
                    } else {
                        // otherwise we should visit that later
                        add n3 to VisitableNodes
                    }
                }
             }
        }
    }
}
// we have not found a circle
return "No circle found in Graph!"

问题是实施。在
CheckedNodes
VisitedNodes
的算法中,我使用集合,它们(带有整数索引)可以通过布尔数组(或类似的东西)轻松实现。
VisitableNodes
是一个列表,它应该由一个类似列表的结构来实现。

这不就是在扩展的图上做一个DFS或BFS吗?我不相信这个算法会有任何效果,似乎如果一个节点定义在多行上,就像OP的例子中,节点1有两个单独的行,
1 2 3
1 4 4
,则此算法将失败。@dicarl2行“对于从n2开始的所有行”将考虑所有“行”。因此,将同时处理
1 2 3
1 4 4
,并将节点2、3、4添加到VisitableNodes中。@templatetypedef这取决于实现。如果
VisitableNodes
是一个列表,那么它就是BFS;如果
VisitableNodes
是一个堆栈,那么它就是DFS。是的,但我相信@templatetypedef有其他想法,他是对的。您的解决方案是在展开图上进行简单的遍历,而问题要复杂得多。你的方法需要时间O(| V |+| E |),但这里| E |!=而且可以非常非常大。问题需要解O(n+m),我们只能使用这个图的压缩形式。