LCA(最近公共祖先)之倍增算法
概述
对于有根树T的两个结点u、v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u、v的祖先且x的深度尽可能大。

如图,3和5的最近公共祖先是1,5和2的最近公共祖先是4
在本篇中我们先介绍一下倍增算法
我们需要一个数组de[i]来表示每一个节点i的深度,用另一数组parent[i][j]来表示每一节点j向上走2的i次方是哪个节点
我们首先在初始化中算出每个点的深度和它的上一个点是什么(用parent[0][i]表示)
在此后我们进行倍增的处理:parent[1][j]=parent[0][parent[0][j]]......parent[i+1][j]=parent[i][parent[i][j]]
当然如果已经走到根节点了,就将其它的parent全设为0
然后我们就可以搞lca了:给你两个点想x,y,让y成为深的那个,如果x,y深度不等就让y倍增地往上跳。
当x,y深度相等时凡是它俩不相等就倍增地跳,最后它们中任意一个的父节点及他们的最近公共祖先
模板
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
const int LOG=18;
vector<int>g[500010];
int de[500010];
int parent[LOG+3][500010];
void dfs(int now,int dep,int be)
{ parent[0][now]=be;
de[now]=dep;
for(int i=0;i<g[now].size();i++)
if(g[now][i]!=be)
dfs(g[now][i],dep+1,now);
}
int lca(int x,int y)
{ if(de[x]>de[y])swap(x,y);
for(int i=LOG;i>=0;i--)
if(de[parent[i][y]]>=de[x]&&parent[i][y]>0)
y=parent[i][y];
if(x==y)return x;
for(int i=LOG;i>=0;i--)
if(parent[i][x]!=parent[i][y])
x=parent[i][x],y=parent[i][y];
return parent[0][x];
}
int main()
{ int n,m,s,i,j,k,p,q;
scanf("%d%d%d",&n,&m,&s);
for(i=1;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
g[x].push_back(y);
g[y].push_back(x);
}
dfs(s,0,0);
for(i=0;i<LOG;i++)
for(j=1;j<=n;j++)
if(parent[i][j]<=0)parent[i+1][j]=-1;
else parent[i+1][j]=parent[i][parent[i][j]];
for(i=1;i<=m;i++){
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",lca(x,y));
}
return 0;
}
LCA(最近公共祖先)之倍增算法的更多相关文章
- LCA 最近公共祖先 Tarjan(离线)算法的基本思路及其算法实现
首先是最近公共祖先的概念(什么是最近公共祖先?): 在一棵没有环的树上,每个节点肯定有其父亲节点和祖先节点,而最近公共祖先,就是两个节点在这棵树上深度最大的公共的祖先节点. 换句话说,就是两个点在这棵 ...
- POJ 1330 LCA最近公共祖先 离线tarjan算法
题意要求一棵树上,两个点的最近公共祖先 即LCA 现学了一下LCA-Tarjan算法,还挺好理解的,这是个离线的算法,先把询问存贮起来,在一遍dfs过程中,找到了对应的询问点,即可输出 原理用了并查集 ...
- caioj 1236 最近公共祖先 树倍增算法模版 倍增
[题目链接:http://caioj.cn/problem.php?id=1236][40eebe4d] 代码:(时间复杂度:nlogn) #include <iostream> #inc ...
- LCA最近公共祖先 Tarjan离线算法
学习博客: http://noalgo.info/476.html 讲的很清楚! 对于一颗树,dfs遍历时,先向下遍历,并且用并查集维护当前节点和父节点的集合.这样如果关于当前节点(A)的关联节点( ...
- Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载)
Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载) 转载自:http://hi.baidu.com/lydrainbowcat/blog/item/2 ...
- P5836 [USACO19DEC]Milk Visits S 从并查集到LCA(最近公共祖先) Tarjan算法 (初级)
为什么以它为例,因为这个最水,LCA唯一黄题. 首先做两道并查集的练习(估计已经忘光了).简单来说并查集就是认爸爸找爸爸的算法.先根据线索理认爸爸,然后查询阶段如果发现他们的爸爸相同,那就是联通一家的 ...
- LCA 近期公共祖先 小结
LCA 近期公共祖先 小结 以poj 1330为例.对LCA的3种经常使用的算法进行介绍,分别为 1. 离线tarjan 2. 基于倍增法的LCA 3. 基于RMQ的LCA 1. 离线tarjan / ...
- LCA(最近公共祖先)模板
Tarjan版本 /* gyt Live up to every day */ #pragma comment(linker,"/STACK:1024000000,1024000000&qu ...
- CodeVs.1036 商务旅行 ( LCA 最近公共祖先 )
CodeVs.1036 商务旅行 ( LCA 最近公共祖先 ) 题意分析 某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间. 假设有N个城镇,首都编号为1,商人从 ...
- LCA近期公共祖先
LCA近期公共祖先 该分析转之:http://kmplayer.iteye.com/blog/604518 1,并查集+dfs 对整个树进行深度优先遍历.并在遍历的过程中不断地把一些眼下可能查询到的而 ...
随机推荐
- html页面的音频问题
导火线 : 负责了项目中的话务间模块,处理音频出了一点问题 之前的处理 : //循环播放声音 var dialAudioDocument = document.createElement('audio ...
- 了解adb的基本原理
ADB就是Android调试桥的意思,很形象.但不知道是windows本身的原因还是windows乱七八糟软件太多,用USB调试手机时,经常连不上ADB,或者就出现offline,导致费时费力,焦头烂 ...
- ssh爆破篇
使用pramiko模块 代码图: import paramiko import sys import time def cont(): b=open(sys.argv[1],'r').read().s ...
- 使用python写天气预告
先去YY天气注册一个账号,然后就能用API了 http://www.yytianqi.com/ # encoding=utf-8import urllib.requestimport jsonimpo ...
- bzoj:1666: [Usaco2006 Oct]Another Cow Number Game 奶牛的数字游戏
Description 奶牛们又在玩一种无聊的数字游戏.输得很郁闷的贝茜想请你写个程序来帮她在开局时预测结果.在游戏的开始,每头牛都会得到一个数N(1<=N<=1,000,000).此时奶 ...
- Dora.Interception, 一个为.NET Core度身打造的AOP框架:不一样的Interceptor定义方式
相较于社区其他主流的AOP框架,Dora.Interception在Interceptor提供了完全不同的编程方式.我们并没有为Interceptor定义一个接口,正是因为不需要实现一个预定义的接口, ...
- 利用object.defineProperty实现数据与视图绑定
如今比较火的mvvm框架,例如vue就是利用es5的defineProperty来实现数据与视图绑定的,下面我来介绍一下defineProperty的用法. var people= {} Object ...
- Redis Cluster集群搭建与应用
1.redis-cluster设计 Redis集群搭建的方式有多种,例如使用zookeeper,但从redis 3.0之后版本支持redis-cluster集群,redis-cluster采用无中心结 ...
- 如何查看dede版本信息
dedecms版本信息 更新日期 it 分类: dedecms 打开 /include/common.inc.php 查找 $cfg_version 可以看到版本号 /打开 data/admin/ve ...
- 织梦中data文件夹是存放什么内容的
dede(织梦)的data文件夹下的文件及文件夹也不少,我们来一个一个的介绍下. 1. admin文件夹 admin文件夹 管理员用到的文件夹,一般是后台的配置文件. 第一个文件,idc.txt 配置 ...