📌  相关文章
📜  后继图

📅  最后修改于: 2021-05-20 05:30:54             🧑  作者: Mango

后继图是一个有向图,其中每个顶点的度数都大于一,即,一个边恰好在每个节点处开始。后继图由一个或多个组件组成,每个组件都包含一个循环以及通往该循环的一些路径。

后继图有时也称为功能图。这样做的原因是,任何后继图形都对应于定义图形边缘的函数。函数的参数是图形的节点,函数提供该节点的后继对象。例如函数

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)时间。但是,使用预处理,可以仅在O(logk)时间中计算succ( x,k )的任何值。

这个想法是预先计算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)的时间。