我想问以下问题:
给出一个有向图(不一定是DAG),对于每个顶点v,从v计算可到达的顶点数。
因此,使用蛮力方法(n倍DFS),我们可以得到O(n ^ 2)时间复杂度的答案。有没有一种更快的计算方法?我绝对可以使用SCC从给定的图形制作DAG。我尝试使用以前计算的值,因此我只能访问每个顶点一次,但是根本无法使用。最大的问题在于这样的图形:
2 -> 1
3 -> 2
3 -> 1
1 -> 4
我从顶点1运行一个DFS并返回结果1。然后,使用它我可以立即计算2的答案(我不再在第二个DFS中输入顶点1,而是使用它的答案),那是2。然后我到达顶点3,并且...该算法将求和1和2的结果,因为我可以到达这两个顶点。但是已经在顶点2的结果中计算了顶点1。这样,我得到的答案等于4,这是不正确的。
答案 0 :(得分:4)
我真的怀疑通用图没有更好的算法。我在主题[1] [2]上找到的所有论文都描述了在O(| V | * | E |)时间运行的算法。
维基百科页面[3]说最快的算法将问题减少为矩阵乘法。
[1] http://ion.uwinnipeg.ca/~ychen2/conferencePapers/tranRelationCopy.pdf
[2] http://www.vldb.org/conf/1988/P382.PDF
[3] http://en.wikipedia.org/wiki/Transitive_closure#Algorithms
答案 1 :(得分:2)
我认为最好的算法运行 O(| V | * | E |)。
算法:
1-对图形进行 SCC 。
2-构建简化图 Gr 。
3-为 Gr 中的每个顶点 v 和每个访问的不同 SCC (包括 v 的 SCC )累积其中的顶点数量(从步骤1开始预先计算)。
使用此算法,您可以消除蛮力 | V | * | V | 因素 O(| V | * | V | + | V | * | E |))< / strong>。
这是我所知道的最好和最简单的算法。我没有示范,但我敢肯定没有更好的办法。