图算法/不相交集

时间:2014-03-17 10:34:05

标签: algorithm graph disjoint-sets

我正在尝试解决this problem但无法快速解决问题。

简而言之 - 我们有一个图表(定向),我们想要找出哪个节点(一组节点可供选择),我们可以访问大多数节点。一个简单的实现是从每个节点运行DFS / BFS并查看我们可以访问的数量。但它太慢了,因为图中有超过5000个节点。运行5000 BFS / DFS需要很长时间。

另一方面,我也觉得这个问题可能与Disjoint Set数据结构有关?但是我无法像在我的不相交的集合实现中那样制定一些上述规则。

有人可以提示如何解决这个问题吗?

1 个答案:

答案 0 :(得分:3)

  1. 使用Strongly Connected Components查找Tarjan's algorithm(SCC) (O(V + E)),并创建SCC图。
  2. Topologically sort生成的SCC图表(它是DAG)。
  3. 从上到下,找到每个组件可以访问的节点数。
  4. 选择SCC中可以达到最大节点数的节点。
  5. 第3步 - 详细说明:

    (为了澄清原因,我将原始图形中的顶点表示为“节点”,并将SCC图形中的顶点表示为“顶点”。

    在步骤3中,您希望找到可从SCC的每个顶点到达的节点数。这可以通过显式查找此集合,或仅查找节点数量来完成:

    1. 明确地找到每个顶点可到达的节点集:
      这非常简单,每个顶点都有一组相关的节点,你需要通过在SCC图上从当前顶点引出的所有边上做一个联合来找到与每个顶点相关的集合。
    2. 使用inclusion/exclusion查找可到达的节点数:
      包含/排除是一种用于计算集合可能在其中重复的集合的大小的技术。例如,如果您有2个集合,则其并集的大小为|A|+|B|- |A[intersection]B|
      对于3组A,B,C:|A|+|B|+|C|-|A[intersrction]B| - |A[intersection]C| - |B[intersection]C + |A[intersection]B[intersection]C|
      (等等)
      使用包含/排除 - 集合是先前的节点,交叉点基于2个不同的顶点,稍后将它们链接到同一个顶点。