2019-11-07 09:25:45

C.树之呼吸-叁之型-树上两点路径长度
Time Limit: 1000 MS Memory Limit: 32768 K
Total Submit: 7 (4 users) Total Accepted: 2 (2 users) Special Judge: No
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-最近公共祖先-倍增法的更多相关文章

  1. LCA最近公共祖先---倍增法笔记

    先暂时把模板写出来,A几道题再来补充 此模板也是洛谷上的一道模板题 P3379 [模板]最近公共祖先(LCA) #pragma GCC optimize(2) //o2优化 #include < ...

  2. LCA (最近公共祖先)倍增做法 —— O(nlogn)预处理 O(logn)(在线)查询

    pa[a][j] 表示 a 结点的 2^j倍祖先(j = 0时 为直接父亲,j = 1时为父亲的父亲……) 1.首先预处理出所有结点的深度值dep和父亲结点 void dfs(int u, int f ...

  3. 洛谷P3379 【模板】最近公共祖先(LCA)(dfs序+倍增)

    P3379 [模板]最近公共祖先(LCA) 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询 ...

  4. 【原创】洛谷 LUOGU P3379 【模板】最近公共祖先(LCA) -> 倍增

    P3379 [模板]最近公共祖先(LCA) 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询 ...

  5. [总结]最近公共祖先(倍增求LCA)

    目录 一.定义 二.LCA的实现流程 1. 预处理 2. 计算LCA 三.例题 例1:P3379 [模板]最近公共祖先(LCA) 四.树上差分 1. 边差分 2. 点差分 3. 例题 一.定义 给定一 ...

  6. 最近公共祖先(LCA)学习笔记 | P3379 【模板】最近公共祖先(LCA)题解

    研究了LCA,写篇笔记记录一下. 讲解使用例题 P3379 [模板]最近公共祖先(LCA). 什么是LCA 最近公共祖先简称 LCA(Lowest Common Ancestor).两个节点的最近公共 ...

  7. 洛谷P3379 【模板】最近公共祖先(LCA)

    P3379 [模板]最近公共祖先(LCA) 152通过 532提交 题目提供者HansBug 标签 难度普及+/提高 提交  讨论  题解 最新讨论 为什么还是超时.... 倍增怎么70!!题解好像有 ...

  8. 「LuoguP3379」 【模板】最近公共祖先(LCA)

    题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...

  9. 洛谷——P3379 【模板】最近公共祖先(LCA)

    P3379 [模板]最近公共祖先(LCA) 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询 ...

随机推荐

  1. ubuntu 代理设置

    在学习工作中使用vagrant作为开发环境已经有很长一段时间了,使用ubuntu 作为开发系统 在使用中发现,即使修改了apt的source.list源文件,在面对一些开发中需要的软件工具的时候,不可 ...

  2. 10——PHP中的两种数组【索引数组】与【关联数组】

    [索引数组] 用数字作为键名的数组一般叫做索引数组.用字符串表示键的数组就是下面要介绍的关联数组.索引数组的键是整数,而且从0开始以此类推. 索引数组初始化例: <pre name=" ...

  3. Flutter跨平台框架的使用-iOS最新版

    科技引领我们前行 [前言] 1:先简单的介绍下Flutter,它是一款跨平台应用SDK,高性能跨平台实现方案(暂时讨论iOS和Android), 它不同于RN,少了像RN的JS中间桥接层,所以它的性能 ...

  4. Windows 10 右键 在此处打开 CMD

    1. 打开注册表 # 1. 使用快捷键打开 “运行” # win + r # 2. 在 “运行” 中输入 # regedit # 3. 回车 2. 创建与设置 OpenCMDHere # 1. 切换到 ...

  5. EOS2.0环境搭建-centos7

    需要安装启动的有三个组件 nodes,keosd,cleos,看看三者的关系 nodeos:核心程序,用于启动eos节点服务,在后台运行,可以配置不同 插件.该进程负责账户管理.区块生成.共识建立,并 ...

  6. fsLayuiPlugin数据字典使用

    概述 数据字典主要解决下拉框数据填充和数据表格转义处理,一个数据字典可以多处使用. 1.多个页面下拉框使用同样的数据,改一个地方需要把所有页面都要修改 2.数据表格转义代替自己手动写templet解析 ...

  7. 面试总被问分布式ID怎么办? 滴滴(Tinyid)甩给他

    整理了一些Java方面的架构.面试资料(微服务.集群.分布式.中间件等),有需要的小伙伴可以关注公众号[程序员内点事],无套路自行领取 一口气说出 9种 分布式ID生成方式,面试官有点懵了 面试总被问 ...

  8. Flutter Form表单控件超全总结

    注意:无特殊说明,Flutter版本及Dart版本如下: Flutter版本: 1.12.13+hotfix.5 Dart版本: 2.7.0 Form.FormField.TextFormField是 ...

  9. mysql 学习日记 悲观和乐观锁

    理解  悲观锁就是什么事情都是需要小心翼翼,生怕弄错了出大问题, 一般情况下 "增删改" 都是有事务在进行操作的,但是 "查" 是不需要事务操作的, 但是凡事没 ...

  10. 简述N种排序算法

    排序算法概述 排序算法是程序员日常很常见的算法,基本上每天都会使用排序,在这里将进行一下总结. 排序算法大致可分为比较类排序和非比较类排序二种,其核心区别可以简单的理解为非比较类排序是对比较类排序之前 ...