令G =(V,E)为有向图,k为整数。我需要在线性时间内找到顶点组,以便该组中的每个顶点可以精确到达k个顶点(包括它自己)。
我想到的第一件事是使用Kosaraju的算法来找到图中强烈连接的组件。连接组件内的每个顶点都可以至少到达此连接组件中的顶点,因此剩下的就是查看组件的连接方式。但是,我没有提出线性解决方案。
任何提示?
感谢。
答案 0 :(得分:1)
你的第一步是正确的。每个强连接组件可以用一个顶点替换,对于该顶点,可到达顶点的起始数是该组件中的元素数。在替换操作后,我们得到有向无环图。现在,对于每个超顶点,我们想要找到可以从中获得多少个顶点。一种想法是在拓扑上对该图进行排序。在此操作之后,所有箭头指向一个方向。在不失一般性的情况下,我们可以假设它们指向右侧,因此我们的图形或多或少看起来像这样:
a -> b ----> e -> f -> g
\ /
-> c -> d -
对于每个顶点,我们有一个起始计数器,它是从一个强连接组件组装顶点的第一阶段得到的。我们现在想做的是从右到左,每个顶点都有一组可以从中到达的顶点。我们需要的操作是这套的快速合并。这里有帮助Find-Union数据结构。您可以向常规size
和rank
添加一个字段,该字段将存储可到达顶点的数量,并在union
两个集合时更新它。
这将导致几乎线性的时间:O(n * alpha(n))
其中alpha(n)
与Ackermann函数的反函数非常小。对于大量数据,它不会大于5
,因此您可以将其视为常量。
我想知道是否有人可以在没有alpha
的情况下成功。
答案 1 :(得分:0)
我认为第一个答案是不正确的。您可以从scc图中其子的可访问性的并集为每个节点创建可到达的节点组。但是,为了执行此操作,您需要复制儿子的组(否则您会搞乱他们的可访问性) )。因此,如果我没有误解,复杂性最小为n * n或实际上为n * E.那是因为副本需要在联合操作之前进行*,所以你需要为每个节点通过n *(数量的子)。这个的复杂性将是n * E + n(alpha(n)) 。完全冗余因此使用union find ..你可以为每个节点使用n个大小的数组。