【发布时间】:2015-12-24 11:16:32
【问题描述】:
关于 DFS 算法,有另一种方法来检查用邻接矩阵表示的有向图中是否存在环?
我找到了有关矩阵属性的零碎信息。 也许我可以将矩阵 A 与自身相乘 n 次,并检查每个结果矩阵中是否存在非零对角线。
虽然这种方法可能是正确的,但我如何才能显式提取表示循环的顶点列表? 那么这个假设算法的复杂度呢?
提前感谢您的帮助。
【问题讨论】:
-
你的方法是对的,但似乎很难找到确切的顶点
关于 DFS 算法,有另一种方法来检查用邻接矩阵表示的有向图中是否存在环?
我找到了有关矩阵属性的零碎信息。 也许我可以将矩阵 A 与自身相乘 n 次,并检查每个结果矩阵中是否存在非零对角线。
虽然这种方法可能是正确的,但我如何才能显式提取表示循环的顶点列表? 那么这个假设算法的复杂度呢?
提前感谢您的帮助。
【问题讨论】:
假设在n 迭代之后,您有一个矩阵,其中i 行和j 列的单元格是M[n][i][j]
根据定义M[n][i][j] = sum over k (M[n - 1][i][k] * A[k][j])。假设M[13][5][5] > 0,意味着它有一个长度为13的循环,从5开始到5结束。要拥有M[13][5][5] > 0,必须有一些k,这样M[12][5][k] * A[k][5] > 0。假设k = 6,现在您知道循环中的另一个节点 (6)。随之而来的是M[12][5][6] > 0和A[6][5] > 0
要拥有M[12][5][6] > 0,必须有一些k,这样M[11][5][k] * A[k][6] > 0。假设k = 9,现在,您知道循环中的另一个节点(9)。随之而来的是M[11][5][9] > 0 和A[9][6] > 0
然后,您可以重复执行相同的操作以查找循环中的其他节点。
【讨论】:
可以修改深度优先搜索来判断是否存在循环。算法第一次发现之前访问过的节点时,可以从堆栈中提取循环,因为之前找到的节点必须仍在堆栈中;使用用户定义的堆栈而不是调用堆栈是有意义的。复杂度将是O(|V|+|E|),对于未修改的深度优先搜索本身。
【讨论】: