对于Off-Line的Lowest Common Ancestor问题,问题描述如下:
we are given a rooted tree T and an arbitrary set P{(u,v),...} of unordered pairs of nodes in T , and we wish to deter-
mine the least common ancestor of each pair in P .
解决该问题有一个大名鼎鼎的方法 Tarjan’s off-line least-common-ancestors algorithm ,其中用到了disjoint set,算法如下:
To solve the off-line least-common-ancestors problem, the following procedure performs a tree walk of T with the initial call LCA(T.root). We assume that each node is colored WHITE prior to the walk.
LCA(u)
MAKE-SET(u)
FIND-SET(u).ancestor = u
for each child v of u in T
LCA(v)
UNION(u,v)
FIND-SET(u).ancestor = u
u.color = BLACK
for each node v such that {u,v} in P
if v.color == BLACK
print "the least common ancestor of " u "and" v "is" FIND-SET(v).ancestor
该方法的时间复杂度是O(N*α(N) + M),其中N为T的节点数,M为P中的(u,v)的数量, α(N)在一般情况下<=4(关于这个值的解释可参见CLRS的Chapter21)。
但是,如果P中(u,v)数量很少,或者该问题不是Off-Line的,而是实时的,这种方法就不是很有效了,因为这个算法的每一次执行都是对整个树进行处理。如果每次给你一个(u,v)对,你都要执行一遍这个算法,那时间复杂度就成了O(M*N*α(N))。因此,在这种情况下,我们可以考虑下面的方式:
Step 1 :整棵树也是初始化成WHITE
Step 2 :对于一个(u,v),我们首先TREE-FIND(u),在这个过程中,将经过的节点颜色变成BLACK
Step 3 :TREE-FIND(v),在这个过程中,遇到的第一个WHITE节点的前一个节点即是least common ancestor
Step 4 :TREE-FIND(u),将途经的节点颜色变为WHITE,这个善后处理保证了对下一个(u,v)的正确处理
该算法时间复杂度显然为O(lg n),在非Off-Line的问题中显然要比Tarjan’s off-line least-common-ancestors algorithm 快很多。