检测压缩有向图中的循环?

时间:2013-01-11 23:51:01

标签: algorithm data-structures graph-theory

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

  

我们给出了一个n <= 300 000个节点的图形,但是是压缩形式。该形式由m <= 300 000行组成,每行由三个数字给出:a_i,b_i,c_i,这意味着存在从节点a_i到区间[b_i,c_i]的所有节点的有向边。问题是确定给定图中是否存在循环,或者否。

例如输入:(数字n,m,然后是描述图形的m行)

  

4 5

     

1 2 3

     

1 4 4

     

2 3 4

     

3 4 4

     

4 1 1

答案是肯定的(例如周期:1-> 2-> 3-> 4-> 1)

并为此输入:

  

4 4

     

1 2 3

     

1 4 4

     

2 3 4

     

3 4 4

答案是否定的。

所以主要的问题是这个图表真的很大,我无法负担创建它并运行DFS。它必须更快地完成。我的第一个想法是使用拓扑排序算法。如果它工作,那么给定的图形中没有循环,否则存在循环。但是更新节点的程度是困难的(为了在该算法的每个步骤中选择具有deg_in = 0的节点)。我想也许使用区间树会有所帮助 - 当我删除节点v时,我可以看到他的邻接列表(此列表的元素将被给定间隔),并且对于所有间隔减少这些点的deg_in。所以我可以在对数时间检查节点度是多少,但我仍然无法快速更新deg_in = 0的节点列表。我不知道,也许我正在尝试一种无法修复的解决方案?

有人可以帮忙吗?

1 个答案:

答案 0 :(得分: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!"

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