要判断两个顶点之间是否有路径是有效的,例如DFS或BFS,它将在O(V + E)内完成。如何确定两个给定顶点之间是否有多条路径?路径应该是简单的路径,即没有重复的顶点。它不一定是最短的路径。是否可以用O(V + E)完成?告诉存在,不需要给出确切的路径。
答案 0 :(得分:1)
方法1:
从源节点执行常规BFS,但在您探索完整图之前一直持续,直到您找到目标为止。
这应该为您提供从源到目标的路径。
如果您获得多条路径,这些路径将是与源和目标没有共同点的路径(如果发生这种情况,您可以在这里停止)。
现在从源节点进行另一次搜索。
如果我们当前位于上面找到的路径中的节点上,请探索所有邻居(递归地,以DFS方式),除了上面路径中该节点之后的邻居。之后探索那个节点。
一些伪代码可以更好地解释:
path = bfs(source, target)
dfs(n)
visited[n] = true
if path.contains(n)
next = path[path.indexOf(n) + 1] // next node in path after n
for each neighbour n2 of n
if n2 != next and !visited[n2]
if path.contains(n2)
found multiple paths
dfs(n2)
dfs(next)
else
for each neighbour n2 of n
if path.contains(n2)
found multiple paths
dfs(n2)
运行时间仍应为O(|V| + |E|)
。
方法2:
(不是一个好的方法,只看运行时间 - 也许有人看到有效的变化)
通过以下修改从源节点执行BFS:
继续,直到您探索整个图表,而不是直到找到目标。
如果您遇到的访问节点不在同一条路径上(即形成一个循环) [1] ,而不是简单地跳过它,而是在该节点上设置一个标志。
完成BFS后,查看找到的路径,如果有任何节点设置了标志,我们就知道存在多条路径。
运行时间仍应为O(|V||E|)
。
[1]:检查节点是否在同一条路径上并不是很容易有效地完成。基本上你需要一组节点。
一个选项是一组文字节点 - 这里的问题是你必须在每一步复制它,这真的很贵。
在此基础上,一组比特节点会更有效率。对于1000个节点,我们只需要1000位来存储路径。对于非常稀疏的图形(边缘很少的图形),这实际上比文字集更差。
另一种选择是为每个节点分配唯一的素数。在执行BFS时,维护每个路径的所有节点的产品。要检查已访问的节点是否在同一路径上,只需检查产品是否可以被节点的值整除。
答案 1 :(得分:0)
如果禁止所有顶点减去源和目标,则可以删除它们并尝试查找另一个路径。边缘也一样。如果它们可以共享除一个顶点/边缘之外的所有顶点/边缘,则可以尝试在时间路径O(V(V+E))
中删除每个顶点/边缘,或者只是继续DFS并计算路径数。
答案 2 :(得分:0)
您可以使用任意遍历算法一次性完成此操作。
您在顶点s
中开始遍历。
无论何时访问新顶点,都将其标记为已访问,请注意后边缘并继续像往常一样进行遍历。
当您访问已标记为已访问的顶点时,将其标记为两次访问并从遍历分支返回。
即使在访问t
之后,您仍继续遍历。
遍历结束后,您将从t
开始,并使用每个顶点中注明的后边重建路径,这与查找从s
到t
的路径时的方式相同。
当您在此路径上找到至少一个两次访问过的顶点v
时,由于从s
到v
至少有两条路径,因此至少还有两条路径从s
到t
。
如果路径上只有一次访问过的顶点,则只有一条从s
到t
的路径。
此类算法的运行时间为O(|E|)
。