【问题标题】:How to detect if breaking an edge will make a graph disjoint?如何检测打破边是否会使图形不相交?
【发布时间】:2011-02-28 23:54:41
【问题描述】:

我有一个从单个根节点开始的图表。节点被一一添加到图表中。在节点创建时,它们必须通过一条边链接到根节点或另一个节点。边也可以创建和删除(一个接一个,在任意两个节点之间)。可以一次删除一个节点。节点和边的创建、删除操作可以以任意顺序发生。

好的,所以这是我的问题:当删除一条边时,是否可以在恒定时间内确定(即使用 O(1) 算法),如果这样做会将图划分为两个不相交的子图?如果是,那么根节点属于边的哪一边?

我愿意在合理的范围内维护任何有助于推导此信息的其他数据结构。

也许不可能在 O(1) 中做到这一点,如果是这样,任何指向文献的指针都会受到赞赏。

编辑:该图是有向图。

编辑 2:好的,也许我可以将这种情况限制为从根节点删除边。 [编辑 3:实际上不是] 此外,没有边缘落入根节点。

【问题讨论】:

  • 如果要删除连接图和叶节点的边,是否也假设删除叶节点?或者,删除叶节点是否也会删除将其连接到图其余部分的边?
  • @VeeArr:删除叶节点也会删除链接到它的所有边。至于删除连接叶节点和非叶节点的边,应该由问题本身覆盖(删除任意边)。
  • 你为什么不告诉我?!你是the_graph_guy!!

标签: algorithm data-structures graph


【解决方案1】:

正如之前 Moron 所说,您实际上是在图表中寻找桥。

现在,桥是具有所描述属性的边,并且起源和结束于 剪切顶点。 Cut vertex 正是 Bridge 的样子,但在顶点(节点)版本中。

所以我能想到的唯一方法(尽管相当弯曲初始数据结构假设),为此获得 O(1) 复杂度,如果您首先检查图中的每个节点是否是 Cut Vertex 并且然后只需在恒定时间内检查您要删除的边缘是否附加到这两者之一。

查找图中的节点是否为切割顶点需要 O(m+n),其中 m = # 个边,n= # 个节点。

干杯

【讨论】:

    【解决方案2】:

    为了比显而易见的 O(|V|+|E|) 解决方案稍微加快速度,您可以保留一个生成树,该生成树在图形更改时相当容易更新。

    如果生成树中的边 not 被删除,则图不会断开连接并且什么也不做。如果生成树中的一条边被删除了,那么你必须尝试在这两个顶点之间找到一条新的路径(如果找到了,就用它来更新生成树,否则图就断开了)。

    所以,最好的情况是 O(1),最坏的情况是 O(|V|+|E|),但无论如何实现起来都相当简单。

    【讨论】:

    • 您能否解释一下在树的边缘被删除的情况下如何更新生成树?从您写的内容来看,这似乎并不明显。
    • 可能有更好的方法,但是您可以在损坏的生成树的一个“片段”上标记所有顶点,然后在另一个片段中搜索通过边缘。该边成为生成树的一部分。
    【解决方案3】:

    这是有向图吗?以下假设是无向的。

    您要查找的是给定边是否是图中的Bridge。我相信这可以通过遍历寻找包含该边缘的循环来找到,并且将是 O(|V| + |E|)。

    O(1) 太难了。

    您可能会发现在动态图中维护 2 边连通分量可能对您有用。

    Eppstein 等人对此有一篇论文:http://www.ics.uci.edu/~eppstein/pubs/EppGalIta-TR-93-20.pdf

    它可以在允许插入和删除边的 n 个节点的图中维护 2 边连接的组件。每次更新需要 O(sqrt(n)) 时间,每次查询需要 O(log n) 时间。

    所以每次删除时,都可以在 O(logn) 中查询以确定 2 边连通分量的数量是否发生了变化。我想它还可以告诉您特定节点在哪个组件中。

    这篇论文更通用,适用于其他图问题,而不仅仅是 2 个边连通分量。

    我建议您寻找桥梁和动态 2-edge 连接来帮助您入门。

    希望对您有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-21
      • 2014-03-15
      • 2021-07-13
      • 2014-01-24
      • 2014-08-08
      • 2014-09-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多