树链剖分求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个节点,编号分别 ...
随机推荐
- paip.java 架构师之路以及java高级技术
paip.java 架构师之路以及java高级技术 1. Annotation 设计模式... 概念满天飞.ORM,IOC,AOP. Validator lambda4j memcache. 对 ...
- 神马是 NaN,它的类型是神马?怎么测试一个值是否等于 NaN?
NaN 是 Not a Number 的缩写,JavaScript 的一种特殊数值,其类型是 Number,可以通过 isNaN(param) 来判断一个值是否是 NaN: console.log(i ...
- 每天一个linux命令(32):gzip命令
减少文件大小有两个明显的好处,一是可以减少存储空间,二是通过网络传输文件时,可以减少传输的时间.gzip是在Linux系统中经常使用的一个对文件进行压缩和解压缩的命令,既方便又好用.gzip不仅可以用 ...
- 数组的一个强大函数splice,[增,删,改]
// var a = [1,2,3]; // a.splice(0); // console.log(a); >>[] // a.splice(1); // console.log(a); ...
- 各浏览器Iframe对contentWindow、contentDocument、document及frames属性测试
Iframe易于嵌套及管理页面,但经常遇到跨域.父子页面访问问题,对于子页面访问父页面可以兼容性地通过window.Top或window.Parent或window.frameElement等操作,但 ...
- OpenCascade Modeling Algorithms Boolean Operations
Modeling Algorithms Boolean Operations of Opencascade eryar@163.com 布尔操作(Boolean Operations)是通过两个形状( ...
- hibernate(五)核心开发接口与对象的三种状态
本文链接:http://www.orlion.ml/37/ 一.Configuration 1.AnnotationConfiguration 2.进行配置信息的管理 3.configure()方法通 ...
- java中Object.equals()简单用法
/* equals()方法默认的比较两个对象的引用! */ class Child { int num; public Child(int x){ num = x; } //人文的抛出运行时异常的好处 ...
- UTL_FILE
在PL/SQL中,UTL_FILE包提供文本文件输入和输出功能. 可以访问的目录通过初始化参数UTL_FILE_DIR设置. 注意:UTL_FILE只能读取服务器端文本文件,不能读取二进制文件.这时候 ...
- ios见习之-UISearchbar+tableview实现自动搜索自带提示
当做搜索时常常希望能在输入的时候出现搜索关键字,如下效果