一、最近公共祖先(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問題的規模同次