📌  相关文章
📜  后继图

📅  最后修改于: 2021-10-25 05:09:42             🧑  作者: Mango

后继图是一种有向图,其中每个顶点的出度为 1,即恰好有一条边从每个节点开始。后继图由一个或多个组件组成,每个组件包含一个循环和一些通向它的路径。

后继图有时称为功能图。这样做的原因是任何后继图都对应于定义图边的函数。该函数的参数是图的一个节点,该函数给出该节点的后继节点。例如,函数

x 1 2 3 4 5 6 7 8 9
succ(x) 3 5 7 6 2 2 1 6 3

上述函数定义了下图:

由于后继图的每个节点都有一个唯一的后继,因此也可以定义一个函数succ(x, k)来给出当遍历从节点 x开始并向前走k 步时的节点。例如,在上图中succ(4, 6) = 2 ,因为从节点 4步行6 步可以到达节点 2

计算succ( x, k )值的一种直接方法是从节点x开始并向前走k步,这需要O(k)时间。然而,使用预处理,任何succ( x, k ) 的值都可以在O(logk)时间内计算出来。

这个想法是预先计算succ( x, k ) 的所有值,其中k是 2 的幂,至多是u ,其中u是我们将要走的最大步数。这可以有效地完成,因为我们可以使用以下递归:

预先计算值需要O(n*log u)时间,因为为每个节点计算O(log u)值。在上图中,第一个值如下:

x 1 2 3 4 5 6 7 8 9
succ(x, 1) 3 5 7 6 2 2 1 6 3
succ(x, 2) 7 2 1 2 5 5 3 2 7
succ(x, 4) 3 2 7 2 5 5 1 2 3
succ(x, 8) 7 2 1 2 5 5 3 2 7
                 

此后,可以通过将步数 k 表示为 2 的幂之和来计算succ( x, k ) 的任何值。
例如,如果我们想计算succ(x, 11) 的值,我们首先形成表示 11 = 8 + 2 + 1。使用它

succ(x, 11) = succ(succ(succ(x, 8), 2), 1)

例如,在上图中

succ(4, 11) = succ(succ(succ(4, 8), 2), 1) = 5

这种表示总是由O(log k)部分组成,因此计算succ( x, k ) 的值需要O(log k)时间。

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程