树链剖分求LCA
树链剖分中各种数组的作用:
siz[]数组,用来保存以x为根的子树节点个数
top[]数组,用来保存当前节点的所在链的顶端节点
son[]数组,用来保存重儿子
dep[]数组,用来保存当前节点的深度
fa[]数组,用来保存当前节点的父亲
tid[]数组,用来保存树中每个节点剖分后的新编号
rank[]数组,用来保存当前节点在线段树中的位置
树链剖分求LCA据说很快QWQ,反正我在洛谷上评测的时候比倍增整整快了3分之1.
蓝后我们来说怎么用树链剖分求:

1,第一种情况我们要比较的数在一条链上,比如比较3和12,直接返回深度比较小的数就好了
2,第二种情况我们要比较不在一条链上的两个数,比如我们想求一下10和8的LCA,我们只需要比较一下10和8的重链链顶的深度,我们发现竟然一样深,那我们就用比较早发现的10的链顶就好了,我们吧我们要比较的元素变为自己链顶的父亲(这样就可以实现垮链了),所以近下来我们只需要比较3和8就好,我们发现3和8不在一条链上,所以我们比较3和8链顶的深度,发现8的比较深,所以我们把我们要比较的数变成8的链顶的父亲,也就是3,所以这时候我们要比较的数就都在一条链上了,返回深度比较浅的数就好。
今下来是代码环节,我写了洛谷的3379模板题https://www.luogu.org/problem/show?pid=3379#sub
然后我把我ac的代码粘到这里QWQ
#include<cstring>
#include<iostream>
#include<cstdio>
using namespace std;
#define MAX 1000 struct NODE{
int point,next;
NODE(){next=;};
}edge[MAX<<]; int N,M,S;
int siz[MAX],dep[MAX],son[MAX],fa[MAX];
int top[MAX],tip[MAX],rank[MAX],tim=;
int edgenum=,link[MAX]; void ADD(int a,int b)
{
edgenum++;
edge[edgenum].point=b;
edge[edgenum].next=link[a];
link[a]=edgenum;
} void pt()
{
for(int i=;i<=N;i++){
printf("%3d",i);
}
cout<<endl;
for(int i=;i<=N;i++){
printf("%3d",top[i]);
}
} void DFS(int x,int deep)
{
siz[x]=;
dep[x]=deep;
for(int i=link[x];i;i=edge[i].next){
int v=edge[i].point;
if(v!=fa[x]){
fa[v]=x;
DFS(v,deep+);
siz[x]+=siz[v];
if(son[x]==-||siz[v]>siz[son[x]]){
son[x]=v;
}
}
}
} void DFS2(int x,int tp)
{
//cout<<"!";
top[x]=tp;
tip[x]=++tim;
rank[tip[x]]=x;
if(son[x]==-)return ;
DFS2(son[x],tp);
for(int i=link[x];i;i=edge[i].next){
int v=edge[i].point;
if(v!=son[x]&&v!=fa[x]){
DFS2(v,v);
}
}
} int LCA(int a,int b) //重点的注释都在这里
{
while(top[a]!=top[b]){ //如果两个的链顶不相等,我们就把他们往一起靠
if(dep[top[a]]>dep[top[b]]) //看那个点的链顶深度大改变那个点
a=fa[top[a]];
else
b=fa[top[b]];
}
return dep[a]>dep[b]?b:a; //返回时要返回深度比较小的数
} void init()
{
int a,b;
cin>>N>>M>>S;
for(int i=;i<N;i++){
scanf("%d%d%*c",&a,&b);
ADD(a,b);
ADD(b,a);
}
memset(son,-,sizeof(siz));
} void work()
{
int a,b;
for(int i=;i<=M;i++){
scanf("%d%d%*c",&a,&b);
printf("%d\n",LCA(a,b));
}
} int main()
{
init();//初始化
DFS(S,);//树链剖分。两个dfs就行
DFS2(S,S);
work(); //输入询问
//pt(); 调试函数,复制下来你们也可以用
//system("pause");
return ;
}
树链剖分求LCA的更多相关文章
- cogs 2450. 距离 树链剖分求LCA最近公共祖先 快速求树上两点距离 详细讲解 带注释!
2450. 距离 ★★ 输入文件:distance.in 输出文件:distance.out 简单对比时间限制:1 s 内存限制:256 MB [题目描述] 在一个村子里有N个房子,一 ...
- cogs 2109. [NOIP 2015] 运输计划 提高组Day2T3 树链剖分求LCA 二分答案 差分
2109. [NOIP 2015] 运输计划 ★★★☆ 输入文件:transport.in 输出文件:transport.out 简单对比时间限制:3 s 内存限制:256 MB [题 ...
- HDU2586 How far away ? (树链剖分求LCA)
用树链剖分求LCA的模板: 1 #include<iostream> 2 #include<algorithm> 3 using namespace std; 4 const ...
- 【树链剖分】洛谷P3379 树链剖分求LCA
题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...
- 【POJ1330】Nearest Common Ancestors(树链剖分求LCA)
Description A rooted tree is a well-known data structure in computer science and engineering. An exa ...
- 【模板】树链剖分求LCA
洛谷3379 #include<cstdio> #include<algorithm> using namespace std; ,inf=1e9; int n,m,x,y,r ...
- Hdu 2586 树链剖分求LCA
Code: #include<cstdio> #include<cstring> #include<vector> #include<algorithm> ...
- Luogu 2680 NOIP 2015 运输计划(树链剖分,LCA,树状数组,树的重心,二分,差分)
Luogu 2680 NOIP 2015 运输计划(树链剖分,LCA,树状数组,树的重心,二分,差分) Description L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之 ...
- Luogu 2590 [ZJOI2008]树的统计 / HYSBZ 1036 [ZJOI2008]树的统计Count (树链剖分,LCA,线段树)
Luogu 2590 [ZJOI2008]树的统计 / HYSBZ 1036 [ZJOI2008]树的统计Count (树链剖分,LCA,线段树) Description 一棵树上有n个节点,编号分别 ...
随机推荐
- JS的prototype和__proto__ Constructor
一.prototype和__proto__的概念 prototype是 注意是 只有函数的一个属性才有的(每个函数都有一个prototype属性),这个属性是一个指针,指向一个普通对象并且不是原型对象 ...
- Android 代码混淆之部分类不混淆的技巧
在编写Android程序之后,我们通常要代码进行混淆编码,这样才能保证市场上我们的应用不会被别人进行反编译,然后破解,所以此时需要在发布正式版本的时候,有一些类事不能混淆的,比如实现了 Seriali ...
- 那些年我们写过的T-SQL(中篇)
中篇的重点在于,在复杂情况下使用表表达式的查询,尤其是公用表表达式(CTE),也就是非常方便的WITH AS XXX的应用,在SQL代码,这种方式至少可以提高一倍的工作效率.此外开窗函数ROW_NUM ...
- 冒泡排序java代码
冒泡排序就是依次取出最大数,然后依次交换放到数组最后边. 直观写法: public long[] sort(long[] a){ int n = a.length - 1; // Step:1 选出最 ...
- Cwinux源码解析(三)
我在我的 薛途的博客 上发表了新的文章,欢迎各位批评指正. Cwinux源码解析(三)
- Oracle Dataguard之failover
Oracle Dataguard中,角色转换包含两类:Switchover和Failover.上文<Oracle Dataguard之switchover>中,我们已经谈过了switcho ...
- 可视化(番外篇)——在Eclipse RCP中玩转OpenGL
最近在看有关Eclipse RCP方面的东西,鉴于Gephi是使用opengl作为绘图引擎,所以,萌生了在Eclipse RCP下添加画布,使用opengl绘图的想法,网上有博文详细介绍这方面的内容, ...
- 8个前沿的 HTML5 & CSS3 效果【附源码下载】
作为一个前沿的 Web 开发者,对于 HTML5 和 CSS3 技术或多或少都有掌握.前几年这些新技术刚萌芽的时候,开发者们已经使用它们来小试牛刀了,如今这些先进技术已经遍地开发,特别是在移动端大显身 ...
- [java] 汇率换算器实现(2)
[java] 汇率换算器实现(2) // */ // ]]> // */ // ]]> [java] 汇率换算器实现(2) Table of Contents 1 系列文章地址 2 前 ...
- jQuery 图像裁剪插件Jcrop
, // 设置框的最大宽度 setSelect: [ 175, 100, 400, 300 ] }); $('#text-input ...