16

我正在尝试自学图论,现在尝试了解如何在图中找到SCC。我已经阅读了关于 SO 的几个不同的问题/答案(例如,12345678),但我找不到一个可以遵循的完整分步示例。

根据CORMEN (Introduction to Algorithms),一种方法是:

  1. 调用 DFS(G) 计算每个顶点 u 的完成时间 f[u]
  2. 计算转置(G)
  3. 调用 DFS(Transpose(G)),但在 DFS 的主循环中,按 f[u] 递减的顺序考虑顶点(如步骤 1 中计算的)
  4. 将步骤 3 的深度优先森林中每棵树的顶点输出为单独的强连通分量

观察下图(问题是来自这里的 3.4。我在这里这里找到了几个解决方案,但我试图自己分解并理解它。)

在此处输入图像描述

第 1 步:调用 DFS(G) 计算每个顶点 u 的完成时间 f[u]

从顶点 A 开始运行 DFS:

在此处输入图像描述

请注意格式为 [Pre-Vist, Post-Visit] 的 RED 文本

第 2 步:计算转置 (G)

在此处输入图像描述

步骤 3. 调用 DFS(Transpose(G)),但在 DFS 的主循环中,按 f[u] 递减的顺序考虑顶点(如步骤 1 中计算的)

好的,所以顶点按访问后(完成时间)值递减的顺序排列:

{E、B、A、H、G、I、C、D、F、J}

所以在这一步,我们在 G^T 上运行 DFS,但从上面列表中的每个顶点开始:

  • DFS(E):{E}
  • DFS(B):{B}
  • DFS(A):{A}
  • DFS(H): {H, I, G}
  • DFS(G):从列表中删除,因为它已经被访问过
  • DFS(I):从列表中删除,因为它已经被访问过
  • DFS(C): {C, J, F, D}
  • DFS(J):从列表中删除,因为它已经被访问过
  • DFS(F):从列表中删除,因为它已经被访问过
  • DFS(D):从列表中删除,因为它已经被访问过

步骤4:将步骤3的深度优先森林中每棵树的顶点输出为单独的强连通分量。

所以我们有五个强连通分量:{E}, {B}, {A}, {H, I, G}, {C, J, F, D}

这是我认为是正确的。但是,我在这里这里找到的解决方案说 SCC 是 {C,J,F,H,I,G,D} 和 {A,E,B}。我的错误在哪里?

4

2 回答 2

0

您的步骤是正确的,您的答案也是正确的,通过检查您提供的其他答案,您可以看到他们使用了不同的算法:首先您在 G 转置上运行 DFS,然后在 G 上运行无向分量算法处理递减的顶点从上一步开始他们的帖子编号的顺序。

问题是他们在 G 转置而不是在 G 上运行了最后一步,因此得到了一个不正确的答案。如果您从第 98 页开始阅读 Dasgupta,您将看到他们(尝试)使用的算法的详细说明。

于 2015-11-24T22:32:02.417 回答
0

你的答案是正确的。根据 CLRS,“有向图 G = (V,E) 的强连通分量是顶点 C 的最大集合,因此对于每一对顶点 u 和 v,我们都有 u ~> v 和 v ~> u,即顶点 v 和 u 彼此可达。”

如果您假设 {C, J, F, H, I, G, D} 是正确的,则无法从 D 到达 G(在许多其他谬误中),并且与其他集合相同,无法从A到达E。

于 2017-04-13T13:51:05.473 回答