采访中有人问我这个问题,但我无法提出任何体面的解决方案。因此,我告诉他们天真的方法是先找到所有周期,然后选择长度最小的周期。
我很想知道什么是解决此问题的有效方法。
您可以轻松修改Floyd-Warshall算法。(如果您根本不熟悉图论,建议您将其检查一下,例如,获得《算法导论》的副本)。
传统上,您从path[i][i] = 0每个开始i。但是您可以从开始path[i][i] = INFINITY。它不会影响算法本身,因为无论如何都不会在计算中使用这些零(因为path path[i][j]永远不会为k == i或改变k == j)。
path[i][i] = 0
i
path[i][i] = INFINITY
path[i][j]
k == i
k == j
最后,path[i][i]是经过最短循环的长度i。因此,您需要min(path[i][i])为所有人找到i。而且,如果您想要循环本身(而不仅仅是循环长度),则可以像通常使用常规路径一样进行循环:通过k在算法执行期间进行记忆。
path[i][i]
min(path[i][i])
k
此外,您还可以使用Dijkstra的算法来查找经过任何给定节点的最短周期。如果为每个节点运行此修改后的Dijkstra,将获得与Floyd- Warshall相同的结果。而且由于每个Dijkstra是O(n^2),您将获得相同的O(n^3)整体复杂性。
O(n^2)
O(n^3)