LCA算法——倍增
概况
LCA(Lowest Common Ancestors),即最近公共祖先,是指在有根树中,找出某两个结点u和v最近的公共祖先。
#include<bits/stdc++.h>
#include<queue>
using namespace std;
const int N=5e5+5;
int n,m,s;
int root;
int idx=1;
int ver[2*N],nex[2*N],head[2*N],dis[2*N],f[2*N][25];
queue<int>q;
int t; void add(int x,int y) {//邻接表建图
ver[++idx]=y;
nex[idx]=head[x];
head[x]=idx;
return ;
} void bfs() {//bfs会比dfs更加保险
q.push(root);
dis[root]=1;//根节点的深度为1
while(!q.empty()) {
int x=q.front();
q.pop();
for(int i=head[x]; i; i=nex[i]) {//向下一层搜索
int y=ver[i];
if(dis[y]) continue;//防止死循环
dis[y]=dis[x]+1;//深度更新
f[y][0]=x;//2^0=1,即为y的父结点
for(int j=1; j<=t; j++) {
f[y][j]=f[f[y][j-1]][j-1];//更新2^i个祖先
}
q.push(y);
}
}
return ;
} int lca(int x,int y) {
if(dis[x]<dis[y]){//严格规范dis[x]>dis[y]
swap(x,y);
}
for(int i=t; i>=0; i--) {
if(dis[f[x][i]]>=dis[y]) x=f[x][i];//使x和y的深度相同
}
if(x==y) return x;//已经相同,则直接返回x
for(int i=t; i>=0; i--) {
if(f[x][i]!=f[y][i]) {//如果第2^i个祖先不相同,说明还没有到最小公共祖先
x=f[x][i];
y=f[y][i];//更新x,y
}
}
return f[x][0];//返回x的父节点——即最小公共祖先
} int main() {
cin>>n;
t=(log(n)/log(2))+1;
for(int i=1; i<=n; i++) {
int a,b;
cin>>a>>b;
if(b==-1) root=a;
add(a,b);
add(b,a);
}
bfs();
cin>>m;
for(int i=1; i<=m; i++) {
int x,y;
cin>>x>>y;
if(lca(x,y)==x) cout<<1<<endl;
if(lca(x,y)==y) cout<<2<<endl;
if(lca(x,y)!=x&&lca(x,y)!=y) cout<<0<<endl;
}
// for(int i=1;i<=5;i++)cout<<i<<":"<<dis[i]<<endl;
return 0;
}
LCA算法——倍增的更多相关文章
- LCA算法倍增算法(洛谷3379模板题)
倍增(爬树)算法,刚刚学习的算法.对每一个点的父节点,就记录他的2k的父亲. 题目为http://www.luogu.org/problem/show?pid=3379 第一步先记录每一个节点的深度用 ...
- LCA的倍增算法
LCA,即树上两点之间的公共祖先,求这样一个公共祖先有很多种方法: 暴力向上:O(n) 每次将深度大的点往上移动,直至二者相遇 树剖:O(logn) 在O(2n)预处理重链之后,每次就将深度大的沿重链 ...
- 关于LCA的倍增解法的笔记
emmmmm近日刚刚学习了LCA的倍增做法,写一篇BLOG来加强一下印象w 首先 何为LCA? LCA“光辉”是印度斯坦航空公司(HAL)为满足印度空军需要研制的单座单发轻型全天候超音速战斗攻击机,主 ...
- [模板]LCA的倍增求法解析
题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...
- 【图论】tarjan的离线LCA算法
百度百科 Definition&Solution 对于求树上\(u\)和\(v\)两点的LCA,使用在线倍增可以做到\(O(nlogn)\)的复杂度.在NOIP这种毒瘤卡常比赛中,为了代码的效 ...
- LCA + 二分(倍增)
两个最近的点u和v的最近的公共的祖先称为最近公共祖先(LCA).普通的LCA算法,每算一次LCA的时间复杂度为线性o(n); 这里讲LCA + 二分的方法.首先对于任意的节点v,利用其父节点的信息,可 ...
- LCA算法
LCA算法: LCA(Least Common Ancestor),顾名思义,是指在一棵树中,距离两个点最近的两者的公共节点.也就是说,在两个点通往根的道路上,肯定会有公共的节点,我们就是要求找到公共 ...
- LCA算法解析-Tarjan&倍增&RMQ
原文链接http://www.cnblogs.com/zhouzhendong/p/7256007.html UPD(2018-5-13) : 细节修改以及使用了Latex代码,公式更加美观.改的过程 ...
- LCA 算法(二)倍增
介绍一种解决最近公共祖先的在线算法,倍增,它是建立在任意整数的二进制拆分之上. 代码: //LCA:Doubly #include<cstdio> #define swap(a, ...
随机推荐
- swack的wiki站上线
swack的个人wiki网址:www.swack.cn [服务器破旧,速度较慢,见谅!]
- leetcode1637-两点之间不包括任何点的最宽垂直面积
题目 给你 n 个二维平面上的点 points ,其中 points[i] = [xi, yi] ,请你返回两点之间内部不包含任何点的 最宽垂直面积 的宽度. 垂直面积 的定义是固定宽度,而 y 轴上 ...
- If you see someone without smile
If you see someone without smile, give them one of yours. 难怪我每次和不认识的人说话都放肆大笑.
- docker 创建数据卷容器
数据卷容器 --volumes-from 容器名/id 先起一个容器 docker run -it --name docker01 centos 然后同步 docker01 的数据卷 --volume ...
- rm: cannot remove `/tmp/localhost-mysql_cacti_stats.txt': Operation not permitted
[root@DBslave tmp]# chown zabbix.zabbix /tmp/localhost-mysql_cacti_stats.txt
- 分别使用 Python 和 Math.Net 调用优化算法
1. Rosenbrock 函数 在数学最优化中,Rosenbrock 函数是一个用来测试最优化算法性能的非凸函数,由Howard Harry Rosenbrock 在 1960 年提出 .也称为 R ...
- EXPORT和IMPORT使用示例
1 report ztestprog. 2 data:begin of itab1 occurs 0, 3 ff(10), 4 end of itab1. 5 data:itab2 like itab ...
- 24v转3.3v稳压芯片,高效率DC-DC变换器3A输出电流
PW6206系列是一个高精度,高输入电压低静态电流,高速,低功耗降线性稳压器具有高纹波抑制.输入电压高达40V,负载电流为在VOUT=5V和VIN=7V时高达300mA.该设备采用BCD工艺制造.PW ...
- Java 栈的使用
讲栈之前,要先讲一下Deque双端队列 既可以添加到队尾,也可以添加到队首 既可以从队首获取又可以从队尾获取 public interface Deque<E> extends Queue ...
- Markdown特殊字符、数学公式汇总
引自:https://blog.csdn.net/weixin_39653948/article/details/104621249