[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}^+)\ ...
随机推荐
- Linux 系统实时监控 —— Glances
早些时候,我们提到过有很多可以用来监视系统性能的 Linux 系统监视工具. 但我们估计,或许更多的用户会倾向与绝大多数 Linux 发行版都带的工具 (top 命令). top 命令是 Linux ...
- POJ3468 splay
线段树/树状数组裸题,用splay写 splay也是基本操作pushup pushdown 话说我就是找不到全一点的模板,我自己写又全是bug,导致代码风格一直变来变去= = 关键是建树和区间操作(区 ...
- 项目管理理论与实践(5)——UML应用(下)
本篇文章介绍UML的相关知识.参考<UML从入门到精通> 六.状态机视图 1. 概述 状态机视图通过对类对象的生存周期建立模型来描述对象随时间变化的动态行为.状态是给定类的对象的一组属性值 ...
- hdoj-3791-二叉搜索树(二叉搜索树模板题)
#include <cstring> #include <cstdio> #include <iostream> using namespace std; type ...
- PHP Smarty template for website
/****************************************************************************** * PHP Smarty templat ...
- Sortable
d_(:з」∠)_ import React, {Component} from 'react'; import "./app.css"; import Sortable from ...
- Android Studio 学习 - Intent学习
今天开始仔细的学习Intent. 看的比较多,还在消化中,后续继续完善本篇笔记……
- eclipse Git & maven 安装
JDK安装请自行百度. Maven是免安装的.压缩包解压完成后.如解压后放在D:\Server\maven下.接下来配置maven的环境变量: 系统变量:MAVEN_HOME = D:\Server\ ...
- UOJ #55 & 洛谷 P3920 紫荆花之恋 —— 动态点分治+替罪羊树
题目:http://uoj.ac/problem/55 https://www.luogu.org/problemnew/show/P3920 参考博客:https://www.cnblogs.com ...
- javascript一些小的注意点
try...catch 可以测试代码中的错误.try 部分包含需要运行的代码,而 catch 部分包含错误发生时运行的代码. 当try { 里面的代码 出现错误了 }catch(e){ 才执行下面的c ...