洛谷P3379倍增LCA
传送门
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define re register
using namespace std ;
const int maxn = 5 * 1e5 + 4 ;
inline int read () {
int f = 1 , x = 0 ;
char ch = getchar () ;
while (ch > '9' || ch < '0') {if(ch == '-') f = -1 ; ch = getchar () ;}
while (ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + ch - '0' ; ch = getchar () ;}
return x * f ;
}
int n , m , s , x , y , a , b , c , d ;
int head[maxn] , tot ;
struct Edge {
int from , to , next ;
}edge[maxn << 1] ;
inline void add (int u , int v) {
edge[++tot].from = u ;
edge[tot].to = v ;
edge[tot].next = head[u] ;
head[u] = tot ;
}
int dep[maxn] , f[maxn][21] ;
/*
dep数组用来记录当前点的深度
f[i][j]代表距离i 2^j的祖先
*/
inline void dfs (int x , int fa) {
dep[x] = dep[fa] + 1 ;//更新深度
f[x][0] = fa ;//更新父亲结点
for(re int i = 1 ; (1 << i) <= dep[x] ; ++ i)
//预处理出f数组
f[x][i] = f[f[x][i - 1]][i - 1] ;
//x的2^i级祖先 就是 x的2^(i-1)级祖先的2^(i-1)级祖先。
for(re int i = head[x] ; i ; i = edge[i].next) {
int v = edge[i].to ;
if(v != fa) dfs(v , x) ;
//如果v是x的父亲,那么就说明这条边被访问过了,不能再回溯了
}
}
inline int lca (int a , int b) {
if(dep[a] < dep[b]) swap(a , b) ;//让a的深度更深
for(re int i = 18 ; i >= 0 ; -- i) { //让a跳到跟b相同高度上
if((1 << i) <= (dep[a] - dep[b])) {
a = f[a][i] ;
}
}
if(a == b) return a ; //a,b在同一枝上时,此时a,b会在同一位置,返回任意一个
for(re int i = 18 ; i >= 0 ; -- i) { //从大到小跳
if((1 << i) <= dep[a] && (f[a][i] != f[b][i])) {
//如果不相等,就说明该节点的深度还是比LCA大
a = f[a][i] ;
b = f[b][i] ;
//继续跳
}
}
return f[a][0] ;
//此时a和b不是同一个节点,但是a和b的父亲就是a和b的lca。
}
int main () {
n = read () ; m = read () ; s = read () ;
for(re int i = 1 ; i <= n - 1 ; ++ i) {
x = read () ; y = read () ;
add(x , y) ;
add(y , x) ;
}
dfs(s , 0) ;
while(m--) {
a = read () ; b = read () ;
printf("%d\n" , lca(a , b)) ;
}
return 0 ;
}
洛谷P3379倍增LCA的更多相关文章
- 【倍增】洛谷P3379 倍增求LCA
题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...
- 洛谷P3379 【模板】最近公共祖先(LCA)——LCA
给一手链接 https://www.luogu.com.cn/problem/P3379 算是lca的模板吧 #include<cstdio> #include<cstring> ...
- 洛谷P3379 【模板】最近公共祖先(LCA)(dfs序+倍增)
P3379 [模板]最近公共祖先(LCA) 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询 ...
- 倍增求LCA学习笔记(洛谷 P3379 【模板】最近公共祖先(LCA))
倍增求\(LCA\) 倍增基础 从字面意思理解,倍增就是"成倍增长". 一般地,此处的增长并非线性地翻倍,而是在预处理时处理长度为\(2^n(n\in \mathbb{N}^+)\ ...
- 【洛谷 p3379】模板-最近公共祖先(图论--倍增算法求LCA)
题目:给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 解法:倍增. 1 #include<cstdio> 2 #include<cstdlib> 3 #include ...
- 洛谷P3379 【模板】最近公共祖先(LCA)
P3379 [模板]最近公共祖先(LCA) 152通过 532提交 题目提供者HansBug 标签 难度普及+/提高 提交 讨论 题解 最新讨论 为什么还是超时.... 倍增怎么70!!题解好像有 ...
- 洛谷——P3379 【模板】最近公共祖先(LCA)
P3379 [模板]最近公共祖先(LCA) 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询 ...
- 【树链剖分】洛谷P3379 树链剖分求LCA
题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...
- 洛谷 P3379 【模板】最近公共祖先(LCA)
题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...
随机推荐
- QT试验(1)
今天,用Qt Creator写第一个简单的小程序“HelloQt”,运行时报错:error: cannot open C:\Users\敏\AppData\Local\Temp\main.obj.51 ...
- 学习官方示例 - TForm.BorderIcons
本例用一行代码禁用了最大化按钮. unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphi ...
- Spring之jdbcTemplate:增删改
JdbcTemplate增删改数据操作步骤:1.导入jar包:2.设置数据库信息:3.设置数据源:4.调用jdbcTemplate对象中的方法实现操作 package helloworld.jdbcT ...
- BZOJ4036 HAOI2015按位或(概率期望+容斥原理)
考虑min-max容斥,改为求位集合内第一次有位变成1的期望时间.求出一次操作选择了S中的任意1的概率P[S],期望时间即为1/P[S]. 考虑怎么求P[S].P[S]=∑p[s] (s&S& ...
- 【转】如何向XML内插入一个字符串片段
转自:http://bbs.csdn.net/topics/190051229 5楼 string filepath = Server.MapPath("你的xml文件"); ...
- Spring点滴九:Spring bean的延迟初始化
Spring bean延迟初始化: 官网API: By default, ApplicationContext implementations eagerly create and configure ...
- bzoj1018/luogu4246 堵塞的交通 (线段树)
对于一个区间四个角的点,可以用线段树记下来它们两两的联通情况 区间[l,r]通过两个子区间[l,m],[m+1,r]来更新,相当于合并[l,m],[m+1,r],用(m,m+1)这条边来合并 查询a, ...
- Luogu2661 信息传递(图论)
Luogu2661 信息传递(图论) Description 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti ...
- 【疑点】js中的break,continue和return到底怎么用?
转: [疑点]js中的break,continue和return到底怎么用? 为什么要说个?好像很简单,但是我也会迷糊,不懂有时候为什么要用return,然而break和continue也经常和他放在 ...
- OpenStack 网络服务 Neutron 多网卡(提供者网络)(十八)
OpenStack 网络服务 Neutron 多网卡,分为内部网络.外部网络 使用vmware模拟两张网卡 添加网卡 网卡配置 cd /etc/sysconfig/network-scripts cp ...