无向图中的唯一路径

时间:2013-12-09 19:38:44

标签: algorithm graph

要判断两个顶点之间是否有路径是有效的,例如DFS或BFS,它将在O(V + E)内完成。如何确定两个给定顶点之间是否有多条路径?路径应该是简单的路径,即没有重复的顶点。它不一定是最短的路径。是否可以用O(V + E)完成?告诉存在,不需要给出确切的路径。

3 个答案:

答案 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开始,并使用每个顶点中注明的后边重建路径,这与查找从st的路径时的方式相同。

当您在此路径上找到至少一个两次访问过的顶点v时,由于从sv至少有两条路径,因此至少还有两条路径从st

如果路径上只有一次访问过的顶点,则只有一条从st的路径。

此类算法的运行时间为O(|E|)