倍增(爬树)算法,刚刚学习的算法。对每一个点的父节点,就记录他的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模板题)的更多相关文章

  1. 【后缀数组】洛谷P3809模板题

    题目背景 这是一道模板题. 题目描述 读入一个长度为 n n n 的由大小写英文字母或数字组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符在原串中的位置. ...

  2. 【AC自动机】洛谷三道模板题

    [题目链接] https://www.luogu.org/problem/P3808 [题意] 给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过. [题解] 不再介绍基础知识了,就是裸的模 ...

  3. 【最大流ISAP】洛谷P3376模板题

    题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行 ...

  4. 【后缀自动机】洛谷P3804模板题

    题目描述 给定一个只包含小写字母的字符串SSS, 请你求出 SSS 的所有出现次数不为 111 的子串的出现次数乘上该子串长度的最大值. 输入输出格式 输入格式: 一行一个仅包含小写字母的字符串SSS ...

  5. 洛谷 3379 最近公共祖先(LCA 倍增)

    洛谷 3379 最近公共祖先(LCA 倍增) 题意分析 裸的板子题,但是注意这题n上限50w,我用的边表,所以要开到100w才能过,一开始re了两发,发现这个问题了. 代码总览 #include &l ...

  6. 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)

    To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...

  7. 洛谷 P4148 简单题 KD-Tree 模板题

    Code: //洛谷 P4148 简单题 KD-Tree 模板题 #include <cstdio> #include <algorithm> #include <cst ...

  8. 【noip】跟着洛谷刷noip题2

    noip好难呀. 上一个感觉有点长了,重开一个. 36.Vigenère 密码 粘个Openjudge上的代码 #include<cstdio> #include<iostream& ...

  9. [洛谷P1707] 刷题比赛

    洛谷题目连接:刷题比赛 题目背景 nodgd是一个喜欢写程序的同学,前不久洛谷OJ横空出世,nodgd同学当然第一时间来到洛谷OJ刷题.于是发生了一系列有趣的事情,他就打算用这些事情来出题恶心大家-- ...

随机推荐

  1. HTML5新特性之跨文档消息传输

    1.同域限制 所谓“同域限制”是指,出于安全考虑,浏览器只允许脚本与同样协议.同样域名.同样端口的地址进行通信. 2.window.postMessage方法 浏览器限制不同窗口(包括iFrame窗口 ...

  2. 14款让前端开发者心动的jQuery/CSS3插件及源码

    14款让前端开发者心动的jQuery/CSS3插件及源码,一起来看看. 1.jQuery左右滚动banner代码! DEMO演示    /    源码下载 2.jQuery QQ表情插件qqFace ...

  3. Android那些事儿之LBS定位,实践测试lbs

    最近一朋友让我了解下安卓LBS获取位置信息,于是动手实践了一把.搜了一圈发现有篇博文可以参考:Android那些事儿之LBS定位,但是原文作者没有提供源码下载,于是动手实现了,现记录下来备忘,代码附在 ...

  4. Oracle Purchasing QUESTIONS AND ANSWERS

    Topic Summary Topic: CORRECTIONS: Corrections Topic: DELIVER: Receiving Delivery Topic: DROPSHIP: Dr ...

  5. 制作便携版 FireFox 火狐浏览器

    Firefox是一款可高度自定义的开源浏览器: 你可以访问 火狐DIY 定制自己的Firefox安装包, 此外,你还可以自己动手定制一款可以放在U盘随身携带的便携版Firefox火狐浏览器. 制作便携 ...

  6. 实例演示 kino.razor (前端 Javascript 模板工具,Razor 风格)的使用

    前言 对于习惯了 ASP.NET MVC Razor 模板引擎的人来说,比如我,一直在寻找前端 Javascript 端的 Razor 模板工具.这之前,我也了解到很多Javascript 端的模板工 ...

  7. mysql event

    1.定时调用 存储过程 DELIMITER $$ ALTER DEFINER=`root`@`localhost` EVENT `event_stroke_ArchivesReportDataRefr ...

  8. 快乐的JS正则表达式(二)

    在上一篇中介绍了一个test方法,在本文中将使用另外一个,exec方法可以找到匹配的结果并且返回结果以及位置.exec("正则"): 简单测试: var str = "{ ...

  9. sizeof()用法汇总【转载】

    转载自:http://www.cnblogs.com/chengxin1982/archive/2009/01/13/1374575.html 参考:http://blog.csdn.net/free ...

  10. AngularJS 五大特性,加快 Web 应用开发

    AngularJS 是谷歌的一个 JavaScript 框架,旨在简化前端应用程序的开发.如果你在开发单页的应用程序,我敢肯定你已经听说过它.我是 AngularJS 的忠实粉丝,在这篇文章中我将概述 ...