NuclearBaseACE
2018-08-29 21:11:34
给定一棵有根树,若节z既是节点x的祖先,也是节点y的祖先,则称z是x,y的公 共祖先。在x,y的所有公共祖先中,深度最大的一个称为 x,y的最近公共祖先,记为LCA(x,y)。
如图
LCA问题的算法分为离线算法(并查集+DFS)和在线算法(RMQ+DFS) 两种,前者允许在读入所有询问之后一次性给出所有问题的答案,而在线问题要求在回答后一个问题之前必须给出前一个问题的答案。
LCA问题的应用很多,例如它可以用来回答这样的询问 “点u和点v的距离是多少?”,由于在树中两点的简单路是唯一的,所以这个距离等于u到LCA(u,v)再到v的距离,即d[u]+d[v]-2*d[LCA(u,v)]。
由于这个算法在竞赛中使用极少,这里不多说
从u向上走到根节点,并标记所有经过的节点。
再从v向上走到根节点,当第一次遇到已标记的节点时,就找到了LCA(u,v)。
解决LCA问题的Tarjan算法利用并查集在一次DFS中完成所有询问,时间复杂度为O(Na(N)+Q)
举例说明:
设d[i]表示i点的深度, p[i,j] 表示i的2^j倍祖先,使用类似 RMQ 的 ST算法,递推式为 p[i,j]=p[p[i,j-1],j-l]。 可以在 O(NlogN) 的时间内预处理求出每个节点的2^j的祖先。