【问题标题】:Finding all the roots in a directed graph查找有向图中的所有根
【发布时间】:2013-11-25 20:20:46
【问题描述】:

我需要找到一种算法,以在 O(n+m) 时间内找到有向图中的所有根。

我有一个寻找单根的算法:

  1. 在 V 中的某个 v 上运行 DFS(v)。如果结果是单生成树,则 v 是根。否则,结果就是一片树林。然后:
  2. 在最后一棵树的根上运行 DFS(u)。如果结果是单生成树,则 u 是根。否则,图中没有根。

现在,如果我想找到所有的根,每次在最后一棵树的不同顶点上运行上述算法 O(n) 次的最佳方法是什么?假设我找到了一个根,如果另一个根存在,那么它必须在最后一棵树上,那么如果我继续运行上述算法直到收到“不存在根”或直到遍历所有顶点,它是 O(n+m) 吗?

提前致谢!

【问题讨论】:

  • 查找拓扑排序。你的问题仍然没有意义。术语root 仅为根定义。我假设您需要没有传入边的所有顶点?
  • @IvayloStrandjev ...称为"source vertices"
  • 假设您已经正确找到了一个根,然后您可能会找到具有指向该根的路径的顶点。所有这样的顶点都应该是根本身。或者您可以反转所有边的方向并从找到的根执行 DFS 或 BFS。遇到的所有顶点都应该是根。
  • @amitooshacham 正如我所说,IMO 如果你反转所有边的方向并从根进行 DFS 或 BFS,那么你可以获得所有新的根。
  • 是的,反转所有边是 O(n),其中 n 是边数。

标签: algorithm tree root directed-graph


【解决方案1】:

两种方法:

  1. 反转图形并计算 DFS-loop() 并注意没有出边的顶点(如 Abhishek 所说)。

  2. 更高效 - 在图上运行 DFS-loop() 并使用真假表跟踪没有传入边的顶点。

在最坏的情况下,方法 1 需要两倍的时间。

【讨论】:

  • 能否详细说明第二种方法?
  • 但是根据 OP 的定义,根也可以有传入的边。事实上,如果有一个节点没有任何传入边,那么该节点就是树的唯一根,因为它不能从任何其他“可能的根节点”遍历。
  • 图中可以有多个没有传入边的根
  • 如果你的意思是 root 可以有传入的边缘,而不是它是没有传入边缘的 SCC 的一部分。因此,我们使用 Kasaraju 的 SCC 算法将图形简化为 2.> 可以工作的图形。
【解决方案2】:

首先,您应该在图中找到所有强连通分量。要在更精简的时间内构建它,您可以使用 Kosaraju's algorithmTarjan's algorithm。所有根应位于一个这样的组件中。接下来,您会找到没有传入边的强连接组件。如果您有多个这样的组件,则图没有根顶点。如果您只有一个组件,您应该检查是否可以从中访问其他组件,在这种情况下,此组件包含图中的所有根。

旧变种。

您应该计算到顶点的传入边数,这可以在 O(m) 中完成。所有传入边数为零的顶点将成为图的根,为此您将需要 O(n) 时间。

【讨论】:

  • 我认为您混淆了“根”和“源”。除非我弄错了,否则根是可以通过有向边到达每个其他节点的节点。根本身可能有传入边,而且绝对不是每个没有这些边的节点都是根。
猜你喜欢
  • 2020-10-09
  • 1970-01-01
  • 2010-10-07
  • 1970-01-01
  • 2014-01-02
  • 1970-01-01
  • 2016-05-11
  • 1970-01-01
  • 2011-04-30
相关资源
最近更新 更多