树链剖分中各种数组的作用:

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的更多相关文章

  1. cogs 2450. 距离 树链剖分求LCA最近公共祖先 快速求树上两点距离 详细讲解 带注释!

    2450. 距离 ★★   输入文件:distance.in   输出文件:distance.out   简单对比时间限制:1 s   内存限制:256 MB [题目描述] 在一个村子里有N个房子,一 ...

  2. cogs 2109. [NOIP 2015] 运输计划 提高组Day2T3 树链剖分求LCA 二分答案 差分

    2109. [NOIP 2015] 运输计划 ★★★☆   输入文件:transport.in   输出文件:transport.out   简单对比时间限制:3 s   内存限制:256 MB [题 ...

  3. HDU2586 How far away ? (树链剖分求LCA)

    用树链剖分求LCA的模板: 1 #include<iostream> 2 #include<algorithm> 3 using namespace std; 4 const ...

  4. 【树链剖分】洛谷P3379 树链剖分求LCA

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

  5. 【POJ1330】Nearest Common Ancestors(树链剖分求LCA)

    Description A rooted tree is a well-known data structure in computer science and engineering. An exa ...

  6. 【模板】树链剖分求LCA

    洛谷3379 #include<cstdio> #include<algorithm> using namespace std; ,inf=1e9; int n,m,x,y,r ...

  7. Hdu 2586 树链剖分求LCA

    Code: #include<cstdio> #include<cstring> #include<vector> #include<algorithm> ...

  8. Luogu 2680 NOIP 2015 运输计划(树链剖分,LCA,树状数组,树的重心,二分,差分)

    Luogu 2680 NOIP 2015 运输计划(树链剖分,LCA,树状数组,树的重心,二分,差分) Description L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之 ...

  9. Luogu 2590 [ZJOI2008]树的统计 / HYSBZ 1036 [ZJOI2008]树的统计Count (树链剖分,LCA,线段树)

    Luogu 2590 [ZJOI2008]树的统计 / HYSBZ 1036 [ZJOI2008]树的统计Count (树链剖分,LCA,线段树) Description 一棵树上有n个节点,编号分别 ...

随机推荐

  1. Atitit blend mode COLOR_DODGE 混合模式  “颜色减淡”模式

    Atitit blend mode COLOR_DODGE 混合模式  "颜色减淡"模式 1.1. 混合模式是图像处理技术中的一个技术名词1 1.2. 目录1 1.3. 颜色减淡C ...

  2. 使用(POI)SAX处理Excel文件,防止内存溢出

    POISAXReader h2:first-child, body>h1:first-child, body>h1:first-child+h2, body>h3:first-chi ...

  3. Android 神兵利器—— Adb 常用命令

    总结的Android工具类文章: Android 神兵利器-- Adb 常用命令 Android 神兵利器-- Git 常用命令 Adb的全称为Android Debug Bridge,是管理andr ...

  4. 抛弃强大的TFS ,借助于BugTracker.NET + Visual Source Safe + SourceLink搭建项目开发环境

    微软公司的Team Foundation Server是个强大的项目管理工具,如果用.NET开发,它应该是首选的项目管理平台.TFS的成本比较高,而且和Visual Studio集成紧密.比如TSF有 ...

  5. KendoUI系列:Grid

    1.基本使用 <div id="grid"></div> <link href="@Url.Content("~/Content/ ...

  6. python--基础学习(二)判断 、循环、定义函数、继承、调用

    1.判断 if.elif 代码示范 # coding=utf-8 score = 90 if (score>=90): print("完美") print("优秀& ...

  7. nodejs支持ssi实现include shtml页面

    express 对于include的代码默认不处理,直接输出,没办法执行include的内容,但可以通过Nginx实现. 1. 配置nginx设置开启ssi模式. server { … ssi on; ...

  8. [Node.js] 使用node-forge保障Javascript应用的传输安全

    原文地址:http://www.moye.me/2015/12/19/protect_jsapp_tsl_by_using_node-forge/ 引子 半年前的最后一次更新(惭愧  ),提到了对称与 ...

  9. iOS_UIImage_Gif的合成

    /** 1. 数据获取 2. 创建Gif文件 3. 配置Gif属性 4. 单帧添加到gif */ github地址: https://github.com/mancongiOS/UIImage.git ...

  10. Cordova webapp实战开发:(3)后面可能会学到的东西

    在<Cordova webapp实战开发:(2)认识一下Cordova>中我们了解了Cordova和Phonegap的关系,并简要介绍了一下它的架构,以及多平台性,并给大家留了一些作业.我 ...