LCA
最近公共祖先(Lowest Common Ancestors, LCA),是指在有根树中,某两个结点u和v最近的公共祖先。
- u和v的公共祖先是指一个结点既是u的祖先,又是v的祖先。
- u和v最近的公共祖先是指离u和v最近的公共祖先。
- 如果v本身就是u的祖先则u和v最近的公共祖先就是v。
可以利用LCA求解树上任意两点之间的距离。
例如,求u和v之间的距离。如果u和v的最近公共祖先为lca,则u和v之间的距离为u到树根的距离加上v到树根的距离,减去2倍的lca到树根的距离:
\[dist[u]+dist[v]-2* dist[Lca]
\]
求解LCA的方法有很多,包括暴力搜索法,树上倍增法,在线RMQ算法,离线Tarjan算法,树链剖分法。
在线算法:以序列化的方式一个个的处理输入,也就是说在开始时并不需要已经知道所有的输入,在解决一个问题后立即输出结果。
离线算法:在开始时就需要知道问题的所有输入数据,可以一次性回答所有的问题。除了离线Tarjan算法,其它算法均为在线算法。
暴力搜索法
暴力搜索法有两种思路:
第一种是向上标记法:从u向上一直到根结点,标记所有经过的结点;如果v已被标记,则v结点即为LCA(u, v)。否则v也向上走,第一次遇到已标记的结点时,该结点即为LCA(u, v)。
第二种是同步前进法:将u,v中深度较深的那个结点向上走到和深度较浅的结点同一深度,然后两个点一起向上走,直到走到同一个结点,该结点就是u,v的最近公共祖先,记作LCA(u,v)。如果较深的结点u到达v的同一深度时,那个结点正好就是v,则v结点即为LCA(u,v)。
暴力搜索法求解LCA,两种思路的时间复杂度最坏情况下均为\(O(n)\)时间,每一次查询需要\(O(n)\)时间。