这是一个消费税:
设G是具有n个顶点和m个边的加权有向图,其中所有边都具有正权重。有向循环是一个有向路径,它在同一个顶点开始和结束,并包含至少一个边。给出O(n ^ 3)算法以找到G最小总重量的有向循环。将给出O((n ^ 2)* m)算法的部分信用。
这是我的算法。
我做DFS
。每次当我找到back edge
时,我知道我有一个定向循环。
然后我会暂时沿parent array
向后移动(直到我遍历周期中的所有顶点)并计算total weights
。
然后我将此周期的total weight
与min
进行比较。 min
始终采用最小总权重。在DFS完成后,我们也找到了最小的定向循环。
好的,然后是关于时间的复杂性。
老实说,我不知道算法的时间复杂度。
对于DFS,遍历取O(m + n)(如果m是边数,则n是顶点数)。对于每个顶点,它可能指向其祖先之一,从而形成一个循环。当找到一个循环时,需要O(n)来总结总重量。
所以我认为总时间是O(m + n * n)。但显然这是错误的,如消费中所述,最佳时间为O(n ^ 3),正常时间为O(m * n ^ 2)。
任何人都可以帮助我:
答案 0 :(得分:20)
您可以在此处使用Floyd-Warshall算法。
Floyd-Warshall算法找到所有对顶点之间的最短路径。
该算法非常简单,遍历所有对(u,v)
,找到最小化dist(u,v)+dist(v,u)
的对,因为该对指示来自{{1}的循环重量为u
的{{1}}。如果图形也允许自循环(边u
),您还需要单独检查它们,因为算法不会检查这些循环(并且只有它们)。
伪代码:
dist(u,v)+dist(v,u)
(u,u)
实际上是从u到v然后从v到u的路径,这是一个循环。
算法运行时间为run Floyd Warshall on the graph
min <- infinity
vertex <- None
for each pair of vertices u,v
if (dist(u,v) + dist(v,u) < min):
min <- dist(u,v) + dist(v,u)
pair <- (u,v)
return path(u,v) + path(v,u)
,因为floyd-warshall是瓶颈,因为循环需要path(u,v) + path(v,u)
时间。
我认为这里的正确性是微不足道的,但如果你不同意我,请告诉我,我会尝试更好地解释它。
答案 1 :(得分:2)
“对于每个顶点,它可能会指向其中一个祖先,从而形成一个循环”
我认为它可能会指向它的任何祖先,这意味着N
另外,当你从dfs中出来时,你将如何标记顶点,你可能会从其他顶点再次到达那里,它将成为另一个循环。所以这不再是(n + m)dfs了。
3。 在一个dfs期间,我认为顶点应该是看不见的,或者是检查,并且对于检查,你可以存储到起始顶点的路径的最小权重。因此,如果在某个其他阶段,您找到该顶点的边缘,则不必再搜索此路径。 此dfs将找到包含第一个顶点的最小定向循环。并且它是O(n ^ 2)(如果你将图形存储为列表,则为O(n + m))
所以如果要从任何其他顶点做到它将是O(n ^ 3)(O(n *(n + m))
抱歉,我的英语和我不擅长术语
答案 2 :(得分:2)
我的算法是否正确?
没有。让我举一个反例。想象一下,您从u
开始DFS,从p1
到p2
有两条路径u
和v
以及{{1}路径p3
}}返回v
,u
比p1
短。
假设您首先将p2
路径转到p2
,然后按路径v
返回u
。发现了一个周期,但显然它不是最小的。然后,您可以通过p3
路径继续探索u
,但是自p1
完全探索以来,DFS结束时没有找到最小周期。
答案 3 :(得分:0)
我做了类似的事情,但是我没有为dfs使用任何访问数组(这是我的算法正常工作所必需的),因此我意识到我的算法具有指数复杂性。
由于您正在查找所有周期,因此不可能在不到指数时间内找到所有周期,因为可能会有2 ^(e-v + 1)个周期。