[luogu3379]最近公共祖先(树上倍增求LCA)
题意:求最近公共祖先。
解题关键:三种方法,1、st表 2、倍增法 3、tarjan
此次使用倍增模板(最好采用第一种,第二种纯粹是习惯)
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<iostream>
#include<cmath>
using namespace std;
typedef long long ll;
int n,m,root,cnt,u,v,head[],dep[],fa[][];
struct edge{
int nxt;
int to;
}e[];
void add_edge(int u,int v){//单向
e[cnt].to=v;
e[cnt].nxt=head[u];
head[u]=cnt++;
}
void dfs(int u){
for(int i=;(<<i)<=dep[u];i++){
fa[u][i]=fa[fa[u][i-]][i-];
}
for(int i=head[u];~i;i=e[i].nxt){
int v=e[i].to;
if(v==fa[u][]) continue;
fa[v][]=u;
dep[v]=dep[u]+;
dfs(v);
}
}
int lca(int u,int v){
if(dep[u]<dep[v]) swap(u,v);
int d=dep[u]-dep[v];
for(int i=;(<<i)<=d;i++) if(d&(<<i)) u=fa[u][i];//转化到两节点深度相同,类似于快速幂的思想
if(u==v) return u;
for(int i=;i>=;i--){
if(fa[u][i]!=fa[v][i]){
u=fa[u][i];
v=fa[v][i];
}
}
return fa[u][];
}
int main(){
memset(head,-,sizeof head);
scanf("%d%d%d",&n,&m,&root);
for(int i=;i<n;i++){
scanf("%d%d",&u,&v);
add_edge(u,v);
add_edge(v,u);
}
dfs(root);
while(m--){
scanf("%d%d",&u,&v);
printf("%d\n",lca(u,v));
}
return ;
}
2、熟悉的树dp方式
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<iostream>
#include<cmath>
using namespace std;
typedef long long ll;
int n,m,root,cnt,u,v,head[],dep[],par[][];
struct edge{
int nxt;
int to;
}e[];
void add_edge(int u,int v){//单向
e[cnt].to=v;
e[cnt].nxt=head[u];
head[u]=cnt++;
}
void dfs(int u,int fa){
for(int i=;(<<i)<=dep[u];i++){
par[u][i]=par[par[u][i-]][i-];
}
for(int i=head[u];~i;i=e[i].nxt){
int v=e[i].to;
if(v==fa) continue;
par[v][]=u;
dep[v]=dep[u]+;
dfs(v,u);
}
}
int lca(int u,int v){
if(dep[u]<dep[v]) swap(u,v);
int d=dep[u]-dep[v];
for(int i=;(<<i)<=d;i++) if(d&(<<i)) u=par[u][i];//转化到两节点深度相同,类似于快速幂的思想
if(u==v) return u;
for(int i=;i>=;i--){
if(par[u][i]!=par[v][i]){
u=par[u][i];
v=par[v][i];
}
}
return par[u][];
}
int main(){
memset(head,-,sizeof head);
scanf("%d%d%d",&n,&m,&root);
for(int i=;i<n;i++){
scanf("%d%d",&u,&v);
add_edge(u,v);
add_edge(v,u);
}
dfs(root,-);
while(m--){
scanf("%d%d",&u,&v);
printf("%d\n",lca(u,v));
}
return ;
}
[luogu3379]最近公共祖先(树上倍增求LCA)的更多相关文章
- 树上倍增求LCA(最近公共祖先)
前几天做faebdc学长出的模拟题,第三题最后要倍增来优化,在学长的讲解下,尝试的学习和编了一下倍增求LCA(我能说我其他方法也大会吗?..) 倍增求LCA: father[i][j]表示节点i往上跳 ...
- [算法]树上倍增求LCA
LCA指的是最近公共祖先(Least Common Ancestors),如下图所示: 4和5的LCA就是2 那怎么求呢?最粗暴的方法就是先dfs一次,处理出每个点的深度 然后把深度更深的那一个点(4 ...
- [学习笔记] 树上倍增求LCA
倍增这种东西,听起来挺高级,其实功能还没有线段树强大.线段树支持修改.查询,而倍增却不能支持修改,但是代码比线段树简单得多,而且当倍增这种思想被应用到树上时,它的价值就跟坐火箭一样,噌噌噌地往上涨. ...
- 树上倍增求LCA及例题
先瞎扯几句 树上倍增的经典应用是求两个节点的LCA 当然它的作用不仅限于求LCA,还可以维护节点的很多信息 求LCA的方法除了倍增之外,还有树链剖分.离线tarjan ,这两种日后再讲(众人:其实是你 ...
- 树上倍增求LCA详解
LCA(least common ancestors)最近公共祖先 指的就是对于一棵有根树,若结点z既是x的祖先,也是y的祖先(不要告诉我你不知道什么是祖先),那么z就是结点x和y的最近公共祖先. 定 ...
- Codeforces 609E (Kruskal求最小生成树+树上倍增求LCA)
题面 传送门 题目大意: 给定一个无向连通带权图G,对于每条边(u,v,w)" role="presentation" style="position: rel ...
- CF 519E(树上倍增求lca)
传送门:A and B and Lecture Rooms 题意:给定一棵树,每次询问到达点u,v距离相等的点有多少个. 分析:按情况考虑: 1.abs(deep[u]-deep[v])%2==1时, ...
- 树上倍增求LCA
大概思想就是,节点$i$的第$2^{j}$个父节点是他第$2^{j-1}$个父亲的第$2^{j-1}$个父亲 然后可以$O(nlogn)$时间内解决…… 没了? //fa[i][j]表示i的第2^j个 ...
- 倍增求LCA学习笔记(洛谷 P3379 【模板】最近公共祖先(LCA))
倍增求\(LCA\) 倍增基础 从字面意思理解,倍增就是"成倍增长". 一般地,此处的增长并非线性地翻倍,而是在预处理时处理长度为\(2^n(n\in \mathbb{N}^+)\ ...
随机推荐
- 为WPF和Silverlight的Grid添加边框线
http://www.cnblogs.com/chenxizhang/archive/2011/09/22/2185414.html
- [原创]Java动态填充word文档并上传到服务器
一. 需求背景 在一些特殊应用场合,客户希望在服务器上生成文档的同时并填充数据,客户端的页面不显示打开文档,但是服务器上生成文档对服务器压力很大,目前服务器上生成文档第一种就是方式是jacob, 但是 ...
- L117
Hoover has become a household word for a vacuum cleaner through the world.Economics are slowly killi ...
- uva10815(set的应用)
紫书例题,这道题的例程让我长了知识.以前没有用过cctype和stringstream相关的东西.很实用,值得学习. #include <cctype>的函数 c++中应该是#includ ...
- 「2017 山东三轮集训 Day7」Easy
一棵带边权的树,多次询问 $x$ 到编号为 $[l,r]$ 的点最短距离是多少 $n \leq 100000$ sol: 动态点分治,每层重心维护到所有点的距离 查询的时候在管辖这个点的 log 层线 ...
- redis的no-appendfsync-on-rewrite参数
redis提供了两种持久化机制,rdb和aof. 关于aof的原理,类似于预写日志,不再解释.其中几个选项如下: appendfsync always:总是写入aof文件,并完成磁盘同步appendf ...
- HIVE-执行hive的几种方式,和把HIVE保存到本地的几种方式
网上相关教程很多,这里我主要是简单总结下几种常用的方法,方便日后查询. 第一种,在bash中直接通过hive -e命令,并用 > 输出流把执行结果输出到制定文件 hive -e "se ...
- BZOJ2002:[HNOI2010]弹飞绵羊
浅谈分块:https://www.cnblogs.com/AKMer/p/10369816.html 题目传送门:https://lydsy.com/JudgeOnline/problem.php?i ...
- POJ1456:Supermarket(并查集版)
浅谈并查集:https://www.cnblogs.com/AKMer/p/10360090.html 题目传送门:http://poj.org/problem?id=1456 堆作法:https:/ ...
- mysql 备份语句
模板: mysqldump -h IP -u user -p 选项 dbname>d:\db.sql 选项:-f表示有错误时继续 -d 表示--no-create-db, -n表示--no-da ...