树上倍增是求解关于LCA问题的两个在线算法中的一个,在线算法即不需要开始全部读入查询,你给他什么查询,他都能返回它们的LCA。

树上倍增用到一个关键的数组F[i][j],这个表示第i个结点的向上2^j层的结点。在RMQ-ST中用救是这样的数组。

在树上倍增中也是关键点。

最近公共祖先 LCA (Lowest Common Ancestors)-树上倍增

如在上图中,我们要找结点8和7的LCA,从途中我们可以看出是3(这句估计是废话)。采用倍增的思想是这样的

首相判断结点U和V是否在同一层次,即是否深度相同。因为在深度相同后这样后,二者就可以同时向上跳某n层,去识别所到之点是否为它们的LCA。

最近公共祖先 LCA (Lowest Common Ancestors)-树上倍增

如果深度较大(在底下的点),跳到较高的那个点后,发现二者重合了,那么恭喜,LCA已经找到

另外底下的结点向上跳的步数也不是一步一层的,要不然太慢了。而是计算出U和V的高度差,按高度差的对数k(2^k)去跳,因而越来越接近高层结点,直到相等。

最近公共祖先 LCA (Lowest Common Ancestors)-树上倍增

 1 if(depth[u] < depth[v])
 2     {
 3         swap(u,v);//始终让U在最小边,便于理解
 4     }
 5     while(depth[u] != depth[v])//二者不再同一高度
 6     {
 7         u = father[u][lg[ depth[u]-depth[v]]]; //u向上跳 2^(二者高度差的对数)层
 8     }
 9     if(u==v)//重叠直接就是找到LCA
10     {
11         return u;
12     }
View Code

相关文章: