关于LCA和RMQ问题

一、最近公共祖先(Least Common Ancestors)

对于有根树T的两个结点u、v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u、v的祖先且x的深度尽可能大。另一种理解方式是把T理解为一个无向无环图,而LCA(T,u,v)即u到v的最短路上深度最小的点。

这里给出一个LCA的例子:

例一

对于T=<V,E>
V={1,2,3,4,5}
E={(1,2),(1,3),(3,4),(3,5)}

则有:

LCA(T,5,2)=1
LCA(T,3,4)=3
LCA(T,4,5)=3

 
二、RMQ问题(Range Minimum Query)

RMQ问题是指:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在[i,j]里的最小值下标。这时一个RMQ问题的例子:

例二

对数列:5,8,1,3,6,4,9,5,7 有:

RMQ(2,4)=3
RMQ(6,9)=6

RMQ问题与LCA问题的关系紧密,可以相互转换,相应的求解算法也有异曲同工之妙。

下面给出LCA问题向RMQ问题的转化方法。

对树进行深度优先遍历,每当“进入”或回溯到某个结点时,将这个结点的深度存入数组E最后一位。同时记录结点i在数组中第一次出现的位置(事实上就是进入结点i时记录的位置),记做R[i]。如果结点E[i]的深度记做D[i],易见,这时求LCA(T,u,v),就等价于求E[RMQ(D,R[u],R[v])],(R[u]<R[v])。例如,对于第一节的例一,求解步骤如下:

数列E[i]为:1,2,1,3,4,3,5,3,1
R[i]为:1,2,4,5,7
D[i]为:0,1,0,1,2,1,2,1,0

于是有:

LCA(T,5,2) = E[RMQ(D,R[2],R[5])] = E[RMQ(D,2,7)] = E[3] = 1
LCA(T,3,4) = E[RMQ(D,R[3],R[4])] = E[RMQ(D,4,5)] = E[4] = 3
LCA(T,4,5) = E[RMQ(D,R[4],R[5])] = E[RMQ(D,5,7)] = E[6] = 3

易知,转化后得到的数列长度为树的结点数的两倍加一,所以转化后的RMQ问题与LCA问题的规模同次

 http://www.cnblogs.com/cs1003/archive/2012/08/22/2650973.html

posted on 2012-08-22 19:58  一把刷子  阅读(270)  评论(0编辑  收藏  举报