2010-10-12 73 views

回答

19

您可以轻松地修改Floyd-Warshall algorithmAlgorithms in C++ Part5 - Robert Sedgwick。 (如果你根本不熟悉图论,我建议检查一下,例如获得Introduction to Algorithms的副本)。

传统上,您每个i开始path[i][i] = 0。但是你可以从path[i][i] = INFINITY开始。它不会影响算法本身,因为无论如何这些零都不用于计算(因为路径path[i][j]将永远不会改变为k == ik == j)。

最后,path[i][i]是最短周期长度为i的长度。因此,您需要为所有i找到min(path[i][i])。如果你想自行循环(不仅是它的长度),你可以像使用正常路径一样完成它:通过在执行算法期间记住k

另外,您还可以使用Dijkstra's algorithm来查找经过任何给定节点的最短周期。如果你为每个节点运行这个修改后的Dijkstra,你将得到与Floyd-Warshall相同的结果。而且由于每个Dijkstra都是O(n^2),你会得到相同的整体复杂度。

+0

这不符合要求。在这些算法中,最短意味着最小权重而不是最小长度。例如如果有两个周期,例如1,2,3和100,500;那么将选择循环1,但是由于循环2具有最短的长度,所以需要循环2。纠正我,如果我错了。 – 2010-10-12 09:59:51

+0

@Manoj第二个问题是第一个子集。只需将权重1分配给每个边,并且您将收到边数最少的路径。真正的问题(尽管很小)是因为Dijkstra和Floyd-Warshal都找不到从节点回到自身的最短路径。你必须稍微调整一下。 – 2010-10-12 10:52:56

+0

谢谢..我使用Dijkstra的修改版本,它的工作 – 2010-10-12 13:14:20

0
  • 执行DFS
  • DFS期间保持边缘类型的轨道
  • 型边缘的位置是Tree EdgeBack EdgeDown EdgeParent Edge
  • 跟踪,当你得到一个Back Edge并有另一个柜台为了获得长度。

更多细节

+0

不错的尝试,但这最多是指数复杂。我怀疑,罗伯特塞奇威克在他的书中解决了一些更普遍和更复杂的问题,因为这个更容易。 – 2010-10-12 07:52:27

0

你将不得不做的是为每个始终为1的节点分配另一个权重。现在使用这些权重从一个节点到同一节点运行任何最短路径算法。但在考虑中间路径时,您将不得不忽略实际权重为负的路径。

5

伪代码是对Dijkstra算法的简单修改。

for all u in V: 
    for all v in V: 
     path[u][v] = infinity 

for all s in V: 
    path[s][s] = 0 
    H = makequeue (V) .. using pathvalues in path[s] array as keys 
    while H is not empty: 
     u = deletemin(H) 
     for all edges (u,v) in E: 
     if path[s][v] > path[s][u] + l(u, v) or path[s][s] == 0: 
      path[s][v] = path[s][u] + l(u,v) 
     decreaseKey(H, v) 

lengthMinCycle = INT_MAX 

for all v in V: 
    if path[v][v] < lengthMinCycle & path[v][v] != 0 : 
     lengthMinCycle = path[v][v] 

if lengthMinCycle == INT_MAX: 
    print(“The graph is acyclic.”) 

else: 
    print(“Length of minimum cycle is ”, lengthMinCycle) 

时间复杂度:O(| V |^3)