Algorithm 无向图中的唯一路径
要判断两个顶点之间是否有路径是有效的,例如DFS或BFS,将在O(V+E)内完成。确定两个给定顶点之间是否有多条路径如何?路径应该是简单路径,即没有重复的顶点。它不一定是最短的路径。它会用O(V+E)完成吗?只要告诉存在,不需要给出确切的路径 如果禁用除源和目标之外的所有顶点,则可以删除它们并尝试查找其他路径。边也是一样。如果它们可以共享除一个顶点/边以外的所有顶点/边,您可以尝试在时间Algorithm 无向图中的唯一路径,algorithm,graph,Algorithm,Graph,要判断两个顶点之间是否有路径是有效的,例如DFS或BFS,将在O(V+E)内完成。确定两个给定顶点之间是否有多条路径如何?路径应该是简单路径,即没有重复的顶点。它不一定是最短的路径。它会用O(V+E)完成吗?只要告诉存在,不需要给出确切的路径 如果禁用除源和目标之外的所有顶点,则可以删除它们并尝试查找其他路径。边也是一样。如果它们可以共享除一个顶点/边以外的所有顶点/边,您可以尝试在时间O(V(V+E))中删除路径中的每个顶点,或者简单地继续DFS并计算路径数。如果禁止所有减去源和目标的顶点,您
O(V(V+E))
中删除路径中的每个顶点,或者简单地继续DFS并计算路径数。如果禁止所有减去源和目标的顶点,您可以删除它们并尝试查找其他路径。边也是一样。如果它们可以共享除一个顶点/边以外的所有顶点/边,您可以尝试在时间O(V(V+E))
中删除路径中的每个顶点/边,或者简单地继续DFS并计算路径数。方法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: 从源节点执行常规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时,为每个路径维护所有节点的乘积。要检查已访问的节点是否位于同一路径上,只需检查乘积是否可被节点的值整除。您可以使用任意遍历算法一次性完成此操作 在顶点
s
中开始遍历。
无论何时访问一个新顶点,都将其标记为已访问,注意后边缘,并像往常一样继续遍历
访问标记为已访问的顶点时,将其标记为已访问两次并从遍历分支返回
即使在访问了t
之后,也可以继续遍历。
遍历结束后,从t
an开始