[模板] 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,分别表示树的结点个数.询 ...
随机推荐
- 注册免费试用12个月的亚马逊AWS云计算服务
注册: 注册地址 点击页面中间的创建免费用户,进入下一步页面: 然后就是填写各种个人信息的页面了: 填写付款信息: 付款信息会进行一个电话验证,这里需要先填写对应的电话号码和验证码,然后点立刻呼叫我, ...
- 微软手机 能靠Surface Phone卷土重来吗?
能靠Surface Phone卷土重来吗?" title="微软手机 能靠Surface Phone卷土重来吗?"> 就算整体大环境再好,就算是站在风口之上,也总是 ...
- 通过IE私有滤镜让IE6 7 8支持背景透明,内容不透明效果。
CSS3已经支持背景rgba的rgba透明度,这一方法可以避免元素内容也随背景一起变透明(详情请阅http://www.cssha.com/css3-new-knowledge-student).但是 ...
- hexo及next主题修改
通过npm uninstall <package>命令,你可以将node_modules目录下的某个依赖包移除: 1 npm uninstall 包名 要从package.json文件的依 ...
- Autowired和Resource区别
@Autowired和@Resource熟悉吧?是不是经常复制粘贴顺手就来,两者都是用来给成员变量自动装载,可是它俩到底有啥区别呢? 1.@Autowired与@Resource都可以用来装配bean ...
- JobScheduler 和 JobService
使用AlarmManager.IntentService和PendingIntent相互配合,创走周期性的后台任务,实现一个完全可用的后台服务还需要手动执行以下操作. 计划一个周期性任务 ...
- Picaso完美兼容OkHttp3.3,缓存优化两不误 - Tamic Developer"s Blog
为何在Fresco,Glide这么强大的背景下,我又想起了当初的Picasso,又为何写这篇文章?是因为最近项目采用了square公司的RxAndroid,Retrfit和OKhttp, 不得不联想到 ...
- 在博客中显示图片_Mac版
主要是防止自己忘掉 为了解决一开始自己想在写入的博客中添加本地图片,直接链接的话在自己的电脑倒是可以显示图片,但是在别人的电脑上就没办法加载图片了,问各路大神也没人愿意解答,百度也没有想要的答案,只好 ...
- 2020年JAVA大厂笔经面经
个人简介 Java后台开发方向. 非计算机专业硕士,专业涉及到一些开发. 实验室项目主要是Java Web系统,挖掘小亮点. 无实习经验. 闲话唠嗑 回顾这几个月,宛若梦一场. 一开始心态不好 ...
- Python——10模块
*/ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...