LCA最近公共祖先---倍增法笔记
先暂时把模板写出来,A几道题再来补充
此模板也是洛谷上的一道模板题
P3379 【模板】最近公共祖先(LCA)
#pragma GCC optimize(2) //o2优化
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int L = ;//2的指数的大小
const int NN = 1e6+;
int N,M,S; ll bit[L];
int depth[NN];//depth[i]:节点i在树上的深度
int fa[NN][L]; //fa[i][j]:节点i向上走2^j次方的节点
vector<int> G[NN];//存图 void init_log(){//预先把2的多少次方计算出来
bit[] = ;
for(int i = ;i<L;i++)
bit[i] = bit[i-]*;
} void DFS(int u,int par){//u:当前节点 par:u的父亲节点
depth[u] = depth[par]+;
fa[u][] = par;
for(int i = ;i<L;i++){
fa[u][i] = fa[fa[u][i-]][i-];//计算u的各次方的祖先
}
for(auto v: G[u]){//继续去遍历该节点的孩子节点
if(v!=par){//因为是用邻接表存的,所以需要跳过父亲节点
DFS(v,u);
}
}
} int LCA(int a,int b){
if(depth[a] < depth[b]) swap(a,b);//保证深度大的在前,小的在后
int dif = depth[a] - depth[b];//深度差
for(int i = L-;i>=;i--){
if(bit[i] <= dif){//在不超出深度差的范围向上爬
a = fa[a][i];//爬到的位置
dif -= bit[i];//深度差更新
}
}
//此时a,b已经是相同的深度
if(a == b) return a; //如果a,b节点已经相同,所以a,b所在的节点就是lca for(int i = L-;i>=;i--){
if(bit[i] <= depth[a] && fa[a][i] != fa[b][i]){ //bit[i]<=depth[a]:表示不跳出树之外
a = fa[a][i];
b = fa[b][i];
}
}
return fa[a][]; //返回lca的儿子的父亲,也就是lca
} int main(){
// freopen("test.in","r",stdin);
init_log();
cin>>N>>M>>S;
int u,v;
for(int i = ;i<=N-;i++){ //邻接表存图
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
DFS(S,);
int a,b;
for(int i = ;i<=M;i++){
scanf("%d%d",&a,&b);
int lca = LCA(a,b);
printf("%d\n",lca);
} return ;
}
LCA最近公共祖先---倍增法笔记的更多相关文章
- LCA (最近公共祖先)倍增做法 —— O(nlogn)预处理 O(logn)(在线)查询
pa[a][j] 表示 a 结点的 2^j倍祖先(j = 0时 为直接父亲,j = 1时为父亲的父亲……) 1.首先预处理出所有结点的深度值dep和父亲结点 void dfs(int u, int f ...
- poj1330 lca 最近公共祖先问题学习笔记
首先推荐两个博客网址: http://dongxicheng.org/structure/lca-rmq/ http://scturtle.is-programmer.com/posts/30055. ...
- [模板] LCA-最近公共祖先-倍增法
2019-11-07 09:25:45 C.树之呼吸-叁之型-树上两点路径长度 Time Limit: 1000 MS Memory Limit: 32768 K Total Submit: 7 (4 ...
- LCA 近期公共祖先 小结
LCA 近期公共祖先 小结 以poj 1330为例.对LCA的3种经常使用的算法进行介绍,分别为 1. 离线tarjan 2. 基于倍增法的LCA 3. 基于RMQ的LCA 1. 离线tarjan / ...
- LCA(最近公共祖先)模板
Tarjan版本 /* gyt Live up to every day */ #pragma comment(linker,"/STACK:1024000000,1024000000&qu ...
- CodeVs.1036 商务旅行 ( LCA 最近公共祖先 )
CodeVs.1036 商务旅行 ( LCA 最近公共祖先 ) 题意分析 某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间. 假设有N个城镇,首都编号为1,商人从 ...
- lca 最近公共祖先
http://poj.org/problem?id=1330 #include<cstdio> #include<cstring> #include<algorithm& ...
- Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载)
Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载) 转载自:http://hi.baidu.com/lydrainbowcat/blog/item/2 ...
- LCA近期公共祖先
LCA近期公共祖先 该分析转之:http://kmplayer.iteye.com/blog/604518 1,并查集+dfs 对整个树进行深度优先遍历.并在遍历的过程中不断地把一些眼下可能查询到的而 ...
随机推荐
- 用Python玩数据-笔记整理-第一章
第一个程序:print >>>print("Hallo World!") >>>Hallo World! mystring = "Ha ...
- Asp.net之实现自定义跨域
跨域是指在浏览器的同源策略下导致前端和接口部署在不同域下导致无法直接访问的问题. 针对跨域有多种解决方案常见的有: JSNOP: 可参考Jquery实现,缺点是需要后端支持: Access-Con ...
- JavaScript控制语句结构、函数部分
HTML页面代码: <html> <head> <meta charset="UTF-8"> <title>HelloWorld&l ...
- Atlassian In Action-Jira之核心插件(三)
目录 BigPicture BigPicture特点介绍 管理员管理菜单 任务列表 任务管理 设置 最佳实践 Jira Misc Workflow Extensions 最佳实践 自动分配 自动化流程 ...
- 简单分析线程获取ReentrantReadWriteLock 读锁的规则
1. 问题 最近有同事问了我一个问题,在Java编程中,当有一条线程要获取ReentrantReadWriteLock的读锁,此时已经有其他线程获得了读锁,AQS队列里也有线程在等待写锁.由于读锁是共 ...
- PHP -- 数据库访问
一.过时方法(PHP5以前的版本用的):用函数链接数据库,相当于面向过程的方式 //设置页面编码格式 header("content-type:text/html;charset=utf-8 ...
- SpringMVC简易架构图。。。
DispatcherServlet拦截所有请求 -> 通过访问url路径找到对应的控制器 -> 通过适配器调用控制器的方法 -> 控制器里面的方法处理业务 -> 通过视图解析器 ...
- 终极CRUD-2-用lombok提高开发效率
目录 1 lom介绍与基本使用 2 lombok 注意点 2.1 lombok自动生成方法可以混合自己写的方法 2.2 尽量不要使用@Data 2.3 属性不要使用基本类型 2.4 小心@ToStri ...
- 深入学习 Intellij IDEA 调试技巧
程序员的日常工作除了写代码之外,很大一部分时间将会在查找 BUG,解决问题.查找 BUG,离不开在 IDE 中调试代码.熟练的掌握调试技巧,可以帮助我们减少查找时间,快速定位问题. 在 IDEA 中调 ...
- Vue项目的创建和UI资源
Vue项目创建打包与UI资源 1.Vue项目创建 1.1 vue-cli脚手架 vue-cli是一个基于vue的构建工具,用于搭建vue项目的环境,有着兼容,方便,快速的优点,能够完全遵循前后端分离的 ...