我被要求编写一个有效的算法来查找有向图中的所有顶点,这些顶点具有从给定顶点到它们的路径的偶数长度。
这就是我的想法:
(它与DFS的“访问”算法非常相似)
Visit(vertex u)
color[u]<-gray
for each v E adj[u]
for each w E adj[v]
if color[w] = white then
print w
Visit(w)
我认为它有效,但我很难计算它的效率,特别是当图表是循环时。你能帮帮我吗?
答案 0 :(得分:5)
如果我可以提出替代方案 - 我会减少问题并使用DFS而不是修改DFS 。
给定图表G = (V,E)
,创建图G' = (V,E')
,其中E'={(u,v) | there is w in V such that (u,w) and (w,v) are in E)
换句话说 - 我们正在创建一个图G',当且仅当从u到v的路径长度为2时才有边(u,v)。
鉴于该图,我们可以推导出以下算法[高级伪代码] :
s
在G'上运行DFS,并标记标记为DFS的相同节点。解决方案的正确性和时间复杂性分析:
<强>复杂度:强>
复杂性显然是O(min{|V|^2,|E|^2} + |V|)
,因为第1部分 - 因为G'中最多有min{|E|^2,|V|^2}
个边,所以步骤2中的DFS在O(|E'| + |V|) = O(min{|V|^2,|E|^2} + |V|)
中运行
<强>正确性:强>
如果算法发现存在从v0到vk的路径,那么从DFS的正确性 - 在G'上存在路径v0-> v1-> ...-> gt; vk是G上偶数长度的路径v0->v0'->v1->v1'->...->vk
。
如果从G
到v0
的{{1}}上存在均匀长度的路径,请将其设为vk
。然后v0->v1->...->vk
是v0->v2->...->vk
上的路径,将由DFS找到 - 来自DFS的正确性。
作为旁注:
减少问题而不是修改算法通常对错误不太敏感,并且更容易分析和证明正确性,因此在可能的情况下,您通常应该优先考虑修改算法。
编辑:关于您的解决方案:嗯,分析它显示它们几乎完全相同 - 除了我生成G'
作为预处理,并且您正在生成它在每次迭代中,在飞行中。
由于你的解决方案正在产生边缘 - 它可能会做一些工作,然后再做一次。但是,由于每个顶点最多访问一次,因此它最多只能E'
次工作。
为简单起见假设|V|
,为我们的解决方案提供|E| = O(|V|^2)
运行时间的总上限。
它也是下限,查看clique的示例,在任何节点的每个O(|V|^3)
期间,算法将visit()
生成所有可能性,{ {1}}其中一种可能性,因为我们准确访问了O(|V|^2)
个节点,因此总运行时间为visit()
由于我们发现解决方案同时为|V|
和Omega(|V|^3)
,因此总计为O(|V|^3)
答案 1 :(得分:1)