图论——倍增求LCA

 LCA,最近公共祖先。

这是在树上的算法,但是为什么我们把它归为图论呢?

因为它对图论太重要了,其实,树也是图,是任意二节点只有一条路径的图。

我们来看一下LCA的栗子:

这就是LCA,很好理解吧!

那问题来了,怎么实现求两点的LCA呢?

 

其实很简单,用暴力法就可以了。先用树的DFS遍历求出树的深度,在一个一个向父节点搜索,找到一样的就是它们的LCA了!

简单粗暴吧!

 

大家可能会感到疑惑,真的有这么简单?

是的,是这么简单。来回顾一下问题:怎么实现求两点的LCA,DFS是能求,也好求。但是有一个缺点:太慢。

当我们的树的深度很大时,我们无法承受这巨大的复杂度,所以我们要想办法优化它。

 

我们先来看一下暴力解法的代码,并确保你理解了。

code

复制代码
 1 #include <bits/stdc++.h> 2 #define MAXN 100005 3 using namespace std;  4 typedef long long ll;  5 int v[MAXN];//标记节点是否被访问 6 int fa[MAXN];//每个节点的父亲节点 7 int depth[MAXN];//每个节点的深度 8 vector<int>g[MAXN];//vector存树  9 void init()//初始化 10 { 11     memset(v,0,sizeof(v)); 12     memset(depth,0,sizeof(depth)); 13     memset(fa,0,sizeof(fa)); 14     for(int i=0;i<MAXN;i++) 15     { 16         g[i].clear(); 17     } 18 } 19 void dfs(int s,int step)//DFS遍历 20 { 21     depth[s]=step; 22     v[s]=1; 23     for(int i=0;i<g[s].size(); i++) 24 
                        
关键字:
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信