当两个点在一条链上,它们的LCA就是深度较小的那个点。

于是这种树链剖分写LCA的思想就是把要求的两个点想办法靠到一条链上。

而且要靠到尽量更优的一条链上(重链)。

做法:

预处理出每棵树上的重链(size大的),每个点求出一个top,代表与这个点能靠到最近的一条重链的位置。

求LCA时两个点分别向各自top移动,直到两个点到一条链上,输出深度较小的

细节见代码

#include<cstdio>
#include<iostream>
#define MAXN 500001
using namespace std;
struct edge{int pre,other;}b[MAXN*];
struct node{int last,p,depth,h,child,top;}a[MAXN];
int cnt,N,M,x,y,l,root;
void connect(int x1,int x2)
{
b[++cnt]=(edge){a[x1].last,x2};
a[x1].last=cnt;
}
void dfs1(int x1)                  //第一次dfs预处理size、深度,求出重链 (变量名错了 h就是size)
{
a[x1].depth=a[a[x1].p].depth+;
a[x1].h=;
for(int i=a[x1].last;i;i=b[i].pre)
{
int x2=b[i].other;
if(!a[x2].p&&a[x1].p!=x2)
{
a[x2].p=x1;
dfs1(x2);
a[x1].h+=a[x2].h;
if(a[a[x1].child].h<a[x2].h)a[x1].child=x2;
}
}
}
void dfs2(int x1)                 //第二次dfs预处理top
{ 
if(x1==a[a[x1].p].child)a[x1].top=a[a[x1].p].top;            
else a[x1].top=x1;
for(int i=a[x1].last;i;i=b[i].pre)if(a[b[i].other].p==x1)dfs2(b[i].other);
}
int LCA(int x1,int x2)
{
while(a[x1].top!=a[x2].top)          
{
if(a[a[x1].top].depth>a[a[x2].top].depth)x1=a[a[x1].top].p;
else x2=a[a[x2].top].p;          //深度大的点向top移动
}
return a[x1].depth<a[x2].depth?x1:x2;
}
int main()
{
scanf("%d%d%d",&N,&M,&root);
for(int i=;i<=N-;i++)
{
scanf("%d%d",&x,&y);
connect(x,y);
connect(y,x);
}
dfs1(root);
dfs2(root);
while(M--)
{
scanf("%d%d",&x,&y);
printf("%d\n",LCA(x,y));
}
return ;
}

用树链剖分来写LCA的更多相关文章

  1. 树链剖分 (求LCA,第K祖先,轻重链剖分、长链剖分)

      2020/4/30   15:55 树链剖分是一种十分实用的树的方法,用来处理LCA等祖先问题,以及对一棵树上的节点进行批量修改.权值和查询等有奇效. So, what is 树链剖分? 可以简单 ...

  2. 树链剖分(附带LCA和换根)——基于dfs序的树上优化

    .... 有点懒: 需要先理解几个概念: 1. LCA 2. 线段树(熟练,要不代码能调一天) 3. 图论的基本知识(dfs序的性质) 这大概就好了: 定义: 1.重儿子:一个点所连点树size最大的 ...

  3. BZOJ 3083: 遥远的国度 [树链剖分 DFS序 LCA]

    3083: 遥远的国度 Time Limit: 10 Sec  Memory Limit: 1280 MBSubmit: 3127  Solved: 795[Submit][Status][Discu ...

  4. 数据结构--树链剖分准备之LCA

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

  5. P3379 【模板】最近公共祖先(LCA)(树链剖分)版

    #include <bits/stdc++.h> #define read read() #define up(i,l,r) for(register int i = (l);i < ...

  6. LCA树链剖分

    LCA(Lowest Common Ancestor 最近公共祖先)定义如下:在一棵树中两个节点的LCA为这两个节点所有的公共祖先中深度最大的节点. 比如这棵树 结点5和6的LCA是2,12和7的LC ...

  7. 浅谈树链剖分 F&Q

    这是一篇迟来的博客,由于我懒得写文章,本篇以两个问题阐述笔者对树链剖分的初步理解. Q1:树链剖分解决什么问题? 树链剖分,就是把一棵树剖分成若干连续的链,将这些链里的数据映射在线性数组上维护.比方说 ...

  8. BZOJ 3083: 遥远的国度 dfs序,树链剖分,倍增

    今天再做一天树的题目,明天要开始专攻图论了.做图论十几天之后再把字符串搞搞,区域赛前再把计几看看. 3083: 遥远的国度 Time Limit: 10 Sec  Memory Limit: 128 ...

  9. 【BZOJ4538】【HNOI2016】网络(树链剖分,线段树,堆)

    题目链接,我是真的懒得调题目的格式... 题解 树链剖分搞一下LCA 把线段树弄出来 这只是形式上的线段树 本质上是维护一段区间的一个堆 每次把堆插入节点, 询问的时候查询线段树上的堆的最大值就行了 ...

随机推荐

  1. Install Rails on ubuntu 12.04 LTS

    There are basically there ways to install Rails development environment on your ubuntu linux system, ...

  2. Cocos结构

    基类:CApplicationProtocol 纯虚函数virtual bool applicationDidFinishLaunching() = 0; CCApplication继承于CCAppl ...

  3. Elasticsearch之下载源码

    第一步:进入github.com 第二步: 第三步: 第四步: 第五步: 第六步: 第七步:认识下es的源码目录结构

  4. 《Unix环境高级编程》读书笔记 第10章-信号

    1.引言 信号是软件中断. 信号提供了一种处理异步事件的方法. 2. 信号概念 信号的名字都是以3个字符SIG开头. Linux3.2.0支持31种信号.FreeBSD.Linux和Solaris作为 ...

  5. sass的用法小结(四)进阶篇

    Sass 的数据类型 Sass 既然有了类似编程语言的功能,自然也就有了简单的数据类型.这里简单的介绍一些 Sass 中的数据类型,因为在后面的讨论中要用到有关的内容. Sass 中主要有六种数据类型 ...

  6. 【Paper Reading】Object Recognition from Scale-Invariant Features

    Paper: Object Recognition from Scale-Invariant Features Sorce: http://www.cs.ubc.ca/~lowe/papers/icc ...

  7. C语言Huffman压缩和解压

    符号表结构体: struct node { // 字符串形式存储的Huffman编码 char code[MAX_CODE_LENGTH]; // 这个字符在文件中出现的次数 long count; ...

  8. mariadb数据库基础知识及备份

    数据库介绍 1.什么是数据库? 简单的说,数据库就是一个存放数据的仓库,这个仓库是按照一定的数据结构(数据结构是指数据的组织形式或数据之间的联系)来组织,存储的,我们可以通过数据库提供的多种方法来管理 ...

  9. UT源码+105032014018

    设计佣金问题的程序 commission方法是用来计算销售佣金的需求,手机配件的销售商,手机配件有耳机(headphone).手机壳(Mobile phone shell).手机贴膜(Cellphon ...

  10. 洛谷 P4147 玉蟾宫 (最大子矩形问题)

    这道题用到了悬线法,非常牛逼,可以看这个论文. https://blog.csdn.net/twtsa/article/details/8120269 #include<cstdio> # ...