在图中长时间检测节点的连通性

时间:2014-05-09 01:34:57

标签: algorithm graph-algorithm

我从一个没有边缘的N个节点的图表开始。

然后我继续采取M预定的步骤。

在每个步骤中,我必须在两个节点之间创建边缘,或删除边缘。

在每个步骤之后,我必须打印出图表中有多少个连接的组件。

是否有一种算法可以在M时间线性地解决这个问题?如果没有,在最坏的情况下是否有一个比O(min(M,N) * M)更好的?

编辑:

该计划无法确定M步骤是什么。

我必须从输入中读取,我是应该创建边缘还是删除它,以及我应该创建/删除哪个边缘。

示例输入可能是

N = 4
M = 4
JOIN 1 2
JOIN 2 3
DELETE 2 3
DELETE 1 2

然后我的输出应该是

3 # (1 2) 3 4
2 # (1 2 3) 4
3 # (1 2) 3 4
4 # 1 2 3 4

1 个答案:

答案 0 :(得分:2)

有很多方法可以完全在线解决这个问题,但它们比这个答案更复杂。我建议的算法是维护可用边缘的生成森林,以及生成森林的组件数量(以及图形)。如果我们在线完全攻击这个问题,那么这将是有问题的,因为跨越森林边缘可能会被删除,让我们通过未使用的边缘进行替换。但是,我们知道图表中当前的每个边缘将被删除多久。

我们维护的特定生成林是最大权重生成林,其中每个边的权重是其删除时间。如果删除了属于此生成林的边缘,则没有替换,因为连接其端点所表示的组件的每个其他边缘尚未插入,或者权重较小,已被删除。

由于Sleator和Tarjan,有一个动态树数据结构,也称为链接/剪切树,可以在对数时间内提供以下操作。

Link(u, v, w) - inserts an edge between u and v with weight w;
                u and v must not be connected already

Cut(u, v) - cuts the edge between u and v, if it exists;
            returns a boolean indicating whether an edge was removed

FindMin(u, v) - finds the minimum-weight edge on the path from u to v
                  and returns its endpoints and weight;
                returns null if either u = v or u and v are not connected

要保持林,当插入从u到v的边时,将其删除时间与从u到v的路径上的最小值进行比较。如果最小值不存在,则插入边。如果最小值小于新边缘,则删除最小值并将其替换为新边缘。否则,什么也不做。当删除从u到v的边缘时,尝试将其从林中删除。

此方法的运行时间为O(m log n)。如果你没有动态树,那么它肯定需要很长时间才能实现。我没有使用适当的动态树,而是成功地使用了一个更简单的数据结构,它只将森林存储为一堆带有权重和父指针的节点。然后运行时间是O(m d),其中d是图表的最大直径,如果你很幸运,d比n要小很多。