最近公共祖先 Lowest Common Ancestors

基于深度的LCA算法:  对于两个结点u、v,它们的深度分别为depth(u)、depth(v),对于其公共祖先w,深度为depth(w),u需要向上回溯depth(u)-depth(w)步,v需要depth(v)-depth(w)步。 因此,只需要u,v中深度较大的向上移,直到 depth(u)=depth(v) && 此时指向一个结点。               

 

因此,求出LCA的时间复杂度为O(depth(u)+depth(v));   求深度,只需要进行一次遍历,O(n)。  

如果是完全二叉树的话,相当于深度(下标)已经建立好了,直接根据LCA进行计算。

 

 1 vector<int> G[MAXV];  //
 2 int root;  
 3 
 4 int parent[MAXV];  // 父节点; (并查集)
 5 int depth[MAXV];  // 节点深度
 6 
 7 // v:当前结点   p:父节点   d:深度
 8 void DFS(int v,int p,int d){
 9     parent[v]=p;
10     depth[v]=d;
11     for(auto& p:G[v]){
12         dfs(p,v,d+1);
13     }
14 }
15 
16 void init(){
17     dfs(root,-1,1);
18 }
19 
20 int LCA(int u,int v){
21     while(depth[u]>depth[v]){
22         u=parent[u];
23     }
24     while(depth[u]<depth[v]){
25         v=parent[v];
26     }
27     while(u!=v){
28         u=parent[u];
29         v=parent[v];
30     }
31     return u;
32 }
View Code

 

如果需要查找多对LCA,可以考虑二分查找的性质,来找到最小步数。

 

posted @ 2019-09-11 12:10  B_luePhantom  阅读(141)  评论(0编辑  收藏  举报