最近公共祖先 LCA 倍增算法
来源:互联网 发布:用php做偶数乘法表 编辑:程序博客网 时间:2024/06/05 05:55
最近公共祖先 LCA 倍增算法
倍增算法可以在线求树上两个点的LCA,时间复杂度为nlogn
预处理:通过dfs遍历,记录每个节点到根节点的距离dist[u],深度d[u]
init()求出树上每个节点u的2^i祖先p[u][i]
求最近公共祖先,根据两个节点的的深度,如不同,向上调整深度大的节点,使得两个节点在同一层上,如果正好是祖先结束,否则,将连个节点同时上移,查询最近公共祖先。
void dfs(int u){ for(int i=head[u];i!=-1;i=edge[i].next){ int to=edge[i].to; if(to==p[u][0])continue; d[to]=d[u]+1; dist[to]=dist[u]+edge[i].w; p[to][0]=u; //p[i][0]存i的父节点 dfs(to); }}
i的2^j祖先就是i的(2^(j-1))祖先的2^(j-1)祖先:
void init(){ for(int j=1;(1<<j)<=n;j++){ for(int i=1;i<=n;i++){ p[i][j]=p[p[i][j-1]][j-1]; } }}
LCA:
int lca(int a,int b){ if(d[a]>d[b])swap(a,b); //b在下面 int f=d[b]-d[a];//f是高度差 for(int i=0;(1<<i)<=f;i++){//(1<<i)&f找到f化为2进制后1的位置,移动到相应的位置 if((1<<i)&f)b=p[b][i];//比如f=5(101),先移动2^0祖先,然后再移动2^2祖先 } if(a!=b){ for(int i=(int)log2(N);i>=0;i--){ if(p[a][i]!=p[b][i]){//从最大祖先开始,判断a,b祖先,是否相同 a=p[a][i]; b=p[b][i];//如不相同,a b同时向上移动2^j } } a=p[a][0];//这时a的father就是LCA } return a;}
阅读全文
0 0
- 最近公共祖先 LCA 倍增算法
- 最近公共祖先LCA倍增算法
- LCA(最近公共祖先)倍增算法
- 最近公共祖先 LCA 倍增算法
- 最近公共祖先(LCA)及其倍增算法实现
- c++最近公共祖先LCA(倍增算法和tarjan)
- 倍增LCA(最近公共祖先)算法详解
- [笔记]LCA最近公共祖先---倍增在线算法
- 树上两点最近公共祖先LCA的倍增算法 poj1986
- 最近公共祖先(LCA)---倍增法
- 最近公共祖先(LCA):倍增
- 最近公共祖先 LCA 倍增+Tarjan实现
- poj 1986 最近公共祖先 (lca 倍增)
- 倍增法求最近公共祖先 lca
- 【LCA倍增模板】【poj1330】最近公共祖先
- LCA最近公共祖先算法
- LCA最近公共祖先算法
- LCA最近公共祖先算法
- 孙正义:30年后AI的智商将达到10000,你与机器人之间的智力将差49个半爱恩斯坦
- 如何在iterm2中设置自动远程登录(附跳板机攻略)
- 1052. 卖个萌 (20)
- Linux各种软件配置
- java.lang.OutOfMemoryError:GC overhead limit exceeded填坑心得
- 最近公共祖先 LCA 倍增算法
- linux内核学习笔记3
- usage of API documented @
- 1053. 住房空置率 (20)
- java.lang.OutOfMemoryError: GC overhead limit exceeded
- html5视频标签播放视频时的事件问题
- 48. Rotate Image
- 1054. 求平均值 (20)
- Py玩微信大法之群聊里找老乡