[模板] LCA-最近公共祖先-倍增法
2019-11-07 09:25:45
| C.树之呼吸-叁之型-树上两点路径长度 | |||||
|
|||||
| Description | |||||
|
给一棵 n 个结点的树,结点编号从 1 到 n,并指定 m 号结点为根; 给出 q 个询问,每次询问从编号为 x 的结点到编号为 y 的结点的路径长度。 |
|||||
| Input | |||||
|
输入第一行为一个正整数 T,表示测试数据组数; 对于每组测试数据,输入第一行为三个正整数 n、m、q,表示树的结点数,根结点的编号以及询问数; 接下来 n - 1 行给出树的结构,每行两个正整数 x、y,表示结点 x 与结点 y 有边相连; 接下来 q 行给出询问,每行两个正整数 x、y,表示询问从结点 x 到结点 y 的路径长度; 1 <= T <= 20,1 <= n,q <= 1e5,1 <= m <= n。 |
|||||
| Output | |||||
|
每组测试数据的第一行输出“Case #i:”(不含引号),表示是第 i 组测试数据; 接下来 q 行,每行输出一个整数,表示给出的两结点间的路径长路。 |
|||||
| Sample Input | |||||
| 2 5 2 3 1 4 5 4 2 4 3 2 1 3 5 2 4 1 3 1 2 1 2 1 3 1 1 2 3 |
|||||
| Sample Output | |||||
| Case #1: 3 2 1 Case #2: 0 2 |
|||||
| Author | |||||
| 陈鑫 |
最近公共祖先LCA模板题,
ans=deep[x]-deep[LCA(x,y)]+deep[y]-deep[LCA(x,y)];
#include<bits/stdc++.h>
using namespace std;
const int amn=2e5+;
vector<int> eg[amn];
int n,m,maxh,deep[amn],anc[amn][]; ///maxh为树的最大深度=(int)log2(n)+1,deep为结点的深度,anc为距离结点x路径长度为2^i的结点是哪个
queue<int> q; void bfs(int rt){
q.push(rt);deep[rt]=;
while(q.size()){
int u=q.front();q.pop();
for(int i=;i<eg[u].size();i++){
int v=eg[u][i];
if(deep[v])continue;
deep[v]=deep[u]+; ///深度
anc[v][]=u;
for(int j=;j<=maxh;j++) anc[v][j]=anc[anc[v][j-]][j-]; ///预处理2^k距离
q.push(v);
}
}
}
int Lca(int x,int y){
if(deep[x]<deep[y])swap(x,y); ///我们规定x的深度要比y的深度大,所有若x的深度比y的深度小则要将他们交换
for(int i=maxh;i>=;i--) if(deep[anc[x][i]]>=deep[y])x=anc[x][i]; ///将x和y移到同一深度,为什么是>=,因为anc[x][i]表示距离x结点2^i路径长度的结点时哪个,如果时anc[x][0]则表示距离x结点路径长度为1的结点
if(x==y)return x; ///如果x==y说明y是他们的LCA,现在x==y了,可以任意返回x或y,这里你返回y也行
for(int i=maxh;i>=;i--) if(anc[x][i]!=anc[y][i]){x=anc[x][i];y=anc[y][i];} ///找x和y的LCA
return anc[x][]; ///输出LCA
}
void init(int rt){
memset(deep,,sizeof deep);
memset(anc,,sizeof anc);
maxh=(int)log2(n)+;
bfs(rt);
}
int main(){
int T,Case=,an,x,y,q;scanf("%d",&T);
while(T--){
for(int i=;i<=n;i++)eg[i].clear(); ///用vector存边要加这句
scanf("%d%d%d",&n,&m,&q);
for(int i=;i<n;i++){
scanf("%d%d",&x,&y);
eg[x].push_back(y);
eg[y].push_back(x);
}
init(m);
printf("Case #%d:\n",Case++);
while(q--){
scanf("%d%d",&x,&y);
an=Lca(x,y);
printf("%d\n",deep[x]+deep[y]-*deep[an]); ///(deep[x]-deep[an])+(deep[y]-deep[an]),x到最近公共祖先的深度+y到最近公共祖先的深度
}
}
}
/**
题意: 给一棵 n 个结点的树,结点编号从 1 到 n,并指定 m 号结点为根;
给出 q 个询问,每次询问从编号为 x 的结点到编号为 y 的结点的路径长度。
思路:求出x和y的最近公共祖先,答案是x到最近公共祖先的深度+y到最近公共祖先的深度
**/
[模板] LCA-最近公共祖先-倍增法的更多相关文章
- LCA最近公共祖先---倍增法笔记
先暂时把模板写出来,A几道题再来补充 此模板也是洛谷上的一道模板题 P3379 [模板]最近公共祖先(LCA) #pragma GCC optimize(2) //o2优化 #include < ...
- LCA (最近公共祖先)倍增做法 —— O(nlogn)预处理 O(logn)(在线)查询
pa[a][j] 表示 a 结点的 2^j倍祖先(j = 0时 为直接父亲,j = 1时为父亲的父亲……) 1.首先预处理出所有结点的深度值dep和父亲结点 void dfs(int u, int f ...
- 洛谷P3379 【模板】最近公共祖先(LCA)(dfs序+倍增)
P3379 [模板]最近公共祖先(LCA) 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询 ...
- 【原创】洛谷 LUOGU P3379 【模板】最近公共祖先(LCA) -> 倍增
P3379 [模板]最近公共祖先(LCA) 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询 ...
- [总结]最近公共祖先(倍增求LCA)
目录 一.定义 二.LCA的实现流程 1. 预处理 2. 计算LCA 三.例题 例1:P3379 [模板]最近公共祖先(LCA) 四.树上差分 1. 边差分 2. 点差分 3. 例题 一.定义 给定一 ...
- 最近公共祖先(LCA)学习笔记 | P3379 【模板】最近公共祖先(LCA)题解
研究了LCA,写篇笔记记录一下. 讲解使用例题 P3379 [模板]最近公共祖先(LCA). 什么是LCA 最近公共祖先简称 LCA(Lowest Common Ancestor).两个节点的最近公共 ...
- 洛谷P3379 【模板】最近公共祖先(LCA)
P3379 [模板]最近公共祖先(LCA) 152通过 532提交 题目提供者HansBug 标签 难度普及+/提高 提交 讨论 题解 最新讨论 为什么还是超时.... 倍增怎么70!!题解好像有 ...
- 「LuoguP3379」 【模板】最近公共祖先(LCA)
题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...
- 洛谷——P3379 【模板】最近公共祖先(LCA)
P3379 [模板]最近公共祖先(LCA) 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询 ...
随机推荐
- RocketMQ集群平滑下线或重启某个节点
1.现状描述 集群其中一台物理机未知原因导致单用户无法登陆机器,该物理机需要重启修改密码或者重装系统.该台为master节点,运行正常.配置策略为: 异步刷盘 主从异步复制 如果直接下线该master ...
- git指令-删除
git指令-删除 添加一个新文件test.txt到Git并且提交: $ git add test.txt $ git commit -m "add test.txt" [maste ...
- 提取.bank音频包。 Extract .bank audio files
转载请注明出处! 首先我们需要提取的文件是 .bank 的音频文件包,里面包含很条音频. 这是我们会用到工具 step1: 运行 quickbms.exe, 它会自动打开选择文件窗口,我们直接选择下 ...
- Java 八种基本类型和基本类型封装类
1.首先,八种基本数据类型分别是:int.short.float.double.long.boolean.byte.char: 它们的封装类分别是:Integer.Short.Float.Doub ...
- 使用增量备份修复DG中的GAP
问题描述 oracle中DG出现主备不同步现象,alert日志报警有gap信息,但是v$archive_gap视图查不到任何信息.同时主库上的对应归档已经删除且没有备份 解决方案 1.查询备库的scn ...
- 【colab pytorch】使用tensorboardcolab可视化
import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optim from ...
- 使用ajax提交登录
引入jquery-1.10.2.js或者jquery-1.10.2.min.js 页面 <h3>后台系统登录</h3> <form name="MyForm&q ...
- 曹工说mini-dubbo(1)--为了实践动态代理,我写了个简单的rpc框架
相关背景及资源: 之前本来一直在写spring源码解析这块,如下,aop部分刚好写完.以前零散看过一些文章,知道rpc调用基本就是使用动态代理,比如rmi,dubbo,feign调用等.自己也就想着试 ...
- (转)C代码优化方案
C代码优化方案 原文地址:http://www.uml.org.cn/c++/200811103.asp 目录 C代码优化方案 1.选择合适的算法和数据结构 2.使用尽量小的数据类型 3.减少运算的强 ...
- (转)解决windows live writer的段首缩进问题
原文地址:http://blog.csdn.net/xiao_wanpeng/article/details/6381799 Windows live writer 默认是没有段首缩进的,并且不能修改 ...