LCA算法倍增算法(洛谷3379模板题)
倍增(爬树)算法,刚刚学习的算法。对每一个点的父节点,就记录他的2k的父亲。
题目为http://www.luogu.org/problem/show?pid=3379
第一步先记录每一个节点的深度用一个深搜,顺便对每个节点的20赋初值为自己的上一个节点。
第二步通过第一步的初始化对每个节点的2k次进行赋值为fa[i][j]=fa[ fa[i][j-1] ][ j-1 ];自己的j-1次幂的父节点的i-1次就是就是自己的j次幂。
第三步对询问做出处理
1,先判断x,y的深度,如果x比y浅就换位置,让x为深的节点
2,让x上升到和y一样的高度
3,找到他们两个第一个相等的点,一直上升2k次,直到不相等了就让x和y等于他,输出的时候输出的值是fa[x][0]也就是他的上一个点,这是他们相等的点。
输入:N、M、S,分别表示树的结点个数、询问的个数和树根结点的序号。
接下来N-1行每行包含两个正整数x、y,表示x结点和y结点只见有一条直接连接的边(数据保证可以构成树)。
接下来M行每行包含两个正整数a、b,表示询问a结点和b结点的最近公共祖先。
输出包含M行,每行包含一个正整数,依次为每一个询问的结果。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
#define MAX 500010
//=================================================
struct NODE{
int next,point;
NODE(){ next=; }
}edge[];
//=================================================
int N,M,S;
int link[MAX],edgenum=,fa[MAX][];
int deep[MAX];
//=================================================
void init();
void ADD(int ,int );
void DFS(int );
void find();
void pt();
int LCA(int x,int y);
//=================================================
int LCA(int x,int y)
{
if(deep[x]<deep[y])swap(x,y); //如果x比y浅,就让他们两个交换,让x为比较深的那个
for(int i=;i>=;i--){ //注意这里是倒叙,从大k到小k,如果x的k次幂比y深或等于y的深度了就让x等于过去,然后k还会减小
if( deep[ fa[x][i] ] >= deep[y] ) //这样x就可以慢慢逼近直到等于y的深度
x=fa[x][i]; //将x上升到跟y一样的高度上
}
if(x==y)return x;
for(int i=;i>=;i--){ //这里和上边一样,倒叙进行
if( fa[x][i]!=fa[y][i] ) //一只循环到x的0次和y的0次相等的时候,但是这个时候x不等于y也不是公共祖先
x=fa[x][i],y=fa[y][i]; //他们的公共祖先是x的0次幂或y的0次幂所以返回的值是fa[x][0];
}
return fa[x][];
}
//=================================================
void pt()
{
for(int i=;i<=M;i++){
int x,y;
scanf("%d%d*c",&x,&y);
printf("%d\n",LCA(x,y));
}
}
//=================================================
void find()
{
for(int i=;i<=;i++){
for(int j=;j<=N;j++){
fa[j][i]=fa[ fa[j][i-] ][i-]; //确定自己的所有倍增父节点
}
}
}
//=================================================
void DFS(int u)
{
for(int i=link[u];i!=;i=edge[i].next){
int v=edge[i].point;
if(deep[v]==){
deep[v]=deep[u]+; //下一个点的深度为这个点的深度加一
fa[v][]=u; //2的0次幂就是自己的父节点
DFS(v);
}
}
}
//=================================================
void ADD(int x,int y)
{
edgenum++;
edge[edgenum].point=y;
edge[edgenum].next=link[x];
link[x]=edgenum;
}
//=================================================
void init()
{
scanf("%d%d%d",&N,&M,&S);
for(int i=;i<N;i++){
int x,y;
scanf("%d%d*c",&x,&y);
ADD(x,y);
ADD(y,x);
}
}
//=================================================
int main()
{
init(); //初始化
deep[S]=;
DFS(S); //深搜找深度
find(); //找每个点的2k次父节点
pt(); //输入询问输出答案
return ;
}
LCA算法倍增算法(洛谷3379模板题)的更多相关文章
- 【后缀数组】洛谷P3809模板题
题目背景 这是一道模板题. 题目描述 读入一个长度为 n n n 的由大小写英文字母或数字组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符在原串中的位置. ...
- 【AC自动机】洛谷三道模板题
[题目链接] https://www.luogu.org/problem/P3808 [题意] 给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过. [题解] 不再介绍基础知识了,就是裸的模 ...
- 【最大流ISAP】洛谷P3376模板题
题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行 ...
- 【后缀自动机】洛谷P3804模板题
题目描述 给定一个只包含小写字母的字符串SSS, 请你求出 SSS 的所有出现次数不为 111 的子串的出现次数乘上该子串长度的最大值. 输入输出格式 输入格式: 一行一个仅包含小写字母的字符串SSS ...
- 洛谷 3379 最近公共祖先(LCA 倍增)
洛谷 3379 最近公共祖先(LCA 倍增) 题意分析 裸的板子题,但是注意这题n上限50w,我用的边表,所以要开到100w才能过,一开始re了两发,发现这个问题了. 代码总览 #include &l ...
- 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)
To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...
- 洛谷 P4148 简单题 KD-Tree 模板题
Code: //洛谷 P4148 简单题 KD-Tree 模板题 #include <cstdio> #include <algorithm> #include <cst ...
- 【noip】跟着洛谷刷noip题2
noip好难呀. 上一个感觉有点长了,重开一个. 36.Vigenère 密码 粘个Openjudge上的代码 #include<cstdio> #include<iostream& ...
- [洛谷P1707] 刷题比赛
洛谷题目连接:刷题比赛 题目背景 nodgd是一个喜欢写程序的同学,前不久洛谷OJ横空出世,nodgd同学当然第一时间来到洛谷OJ刷题.于是发生了一系列有趣的事情,他就打算用这些事情来出题恶心大家-- ...
随机推荐
- System.Diagnostics.Stopwatch
System.Diagnostics.Stopwatch 注意:此类在 .NET Framework 2.0 版中是新增的.MSDN Stopwatch 实例可以测量一个时间间隔的运行时间,也可以测量 ...
- Newtonsoft 自定义输出内容
高级用法 1.忽略某些属性 2.默认值的处理 3.空值的处理 4.支持非公共成员 5.日期处理 6.自定义序列化的字段名称 7.动态决定属性是否序列化 8.枚举值的自定义格式化问题 9.自定义类型转换 ...
- 初探Stage3D(三) 深入研究透视投影矩阵
关于本文 本文主要讲解从数学的角度如何推导出Stage3D中用到的两个投影矩阵 perspectiveLH public function perspectiveLH(width:Number,hei ...
- CAS认证原理图
- android EditText inputType说明
在开发的过程中,通常会用到EditText,如何让虚拟键盘来适应输入框中内容的类型,通常我们都会在xml文件中加入android:inputType="". android:inp ...
- ffmpeg中的sws_scale算法性能测试
经常用到ffmpeg中的sws_scale来进行图像缩放和格式转换,该函数可以使用各种不同算法来对图像进行处理.以前一直很懒,懒得测试和甄 别应该使用哪种算法,最近的工作时间,很多时候需要等待别人.忙 ...
- wow 各职业体验(pvp)
玩过职业 近战 武器战,冰DK,惩戒骑,增强萨,踏风 法系远程 鸟德,痛苦术,火法,奥法 治疗 奶德,奶骑,奶萨 三板甲职业就冰DK 最轻松,增强萨操作最频繁 机动性最好就武器战,踏风最差的,踏风群攻 ...
- PHP实现简单的监控nginx日志文件功能
此功能是为了实现,定时监控nginx生成的日志数据,并将新增的数据提交到一个接口(比如大数据的接口,让大数据来进行分析) define("MAX_SHOW", 8192*5); / ...
- 经典SQL语句大全(网络资源共享)
下列语句部分是Mssql语句,不可以在access中使用. SQL分类: DDL—数据定义语言(CREATE,ALTER,DROP,DECLARE) DML—数据操纵语言(SELECT,DELET ...
- IOS APP上下黑边问题
网上的一种是一个问题, 更换launchImage 后 APP在iPhone5下出现黑边. 原因是:我将Jpg(640*1136)的图片 强制改为Png(640*1136),导致APP出现黑边.