用树链剖分来写LCA
当两个点在一条链上,它们的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的更多相关文章
- 树链剖分 (求LCA,第K祖先,轻重链剖分、长链剖分)
2020/4/30 15:55 树链剖分是一种十分实用的树的方法,用来处理LCA等祖先问题,以及对一棵树上的节点进行批量修改.权值和查询等有奇效. So, what is 树链剖分? 可以简单 ...
- 树链剖分(附带LCA和换根)——基于dfs序的树上优化
.... 有点懒: 需要先理解几个概念: 1. LCA 2. 线段树(熟练,要不代码能调一天) 3. 图论的基本知识(dfs序的性质) 这大概就好了: 定义: 1.重儿子:一个点所连点树size最大的 ...
- BZOJ 3083: 遥远的国度 [树链剖分 DFS序 LCA]
3083: 遥远的国度 Time Limit: 10 Sec Memory Limit: 1280 MBSubmit: 3127 Solved: 795[Submit][Status][Discu ...
- 数据结构--树链剖分准备之LCA
有关LCA的模板题 传送门 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和 ...
- P3379 【模板】最近公共祖先(LCA)(树链剖分)版
#include <bits/stdc++.h> #define read read() #define up(i,l,r) for(register int i = (l);i < ...
- LCA树链剖分
LCA(Lowest Common Ancestor 最近公共祖先)定义如下:在一棵树中两个节点的LCA为这两个节点所有的公共祖先中深度最大的节点. 比如这棵树 结点5和6的LCA是2,12和7的LC ...
- 浅谈树链剖分 F&Q
这是一篇迟来的博客,由于我懒得写文章,本篇以两个问题阐述笔者对树链剖分的初步理解. Q1:树链剖分解决什么问题? 树链剖分,就是把一棵树剖分成若干连续的链,将这些链里的数据映射在线性数组上维护.比方说 ...
- BZOJ 3083: 遥远的国度 dfs序,树链剖分,倍增
今天再做一天树的题目,明天要开始专攻图论了.做图论十几天之后再把字符串搞搞,区域赛前再把计几看看. 3083: 遥远的国度 Time Limit: 10 Sec Memory Limit: 128 ...
- 【BZOJ4538】【HNOI2016】网络(树链剖分,线段树,堆)
题目链接,我是真的懒得调题目的格式... 题解 树链剖分搞一下LCA 把线段树弄出来 这只是形式上的线段树 本质上是维护一段区间的一个堆 每次把堆插入节点, 询问的时候查询线段树上的堆的最大值就行了 ...
随机推荐
- Install Rails on ubuntu 12.04 LTS
There are basically there ways to install Rails development environment on your ubuntu linux system, ...
- Cocos结构
基类:CApplicationProtocol 纯虚函数virtual bool applicationDidFinishLaunching() = 0; CCApplication继承于CCAppl ...
- Elasticsearch之下载源码
第一步:进入github.com 第二步: 第三步: 第四步: 第五步: 第六步: 第七步:认识下es的源码目录结构
- 《Unix环境高级编程》读书笔记 第10章-信号
1.引言 信号是软件中断. 信号提供了一种处理异步事件的方法. 2. 信号概念 信号的名字都是以3个字符SIG开头. Linux3.2.0支持31种信号.FreeBSD.Linux和Solaris作为 ...
- sass的用法小结(四)进阶篇
Sass 的数据类型 Sass 既然有了类似编程语言的功能,自然也就有了简单的数据类型.这里简单的介绍一些 Sass 中的数据类型,因为在后面的讨论中要用到有关的内容. Sass 中主要有六种数据类型 ...
- 【Paper Reading】Object Recognition from Scale-Invariant Features
Paper: Object Recognition from Scale-Invariant Features Sorce: http://www.cs.ubc.ca/~lowe/papers/icc ...
- C语言Huffman压缩和解压
符号表结构体: struct node { // 字符串形式存储的Huffman编码 char code[MAX_CODE_LENGTH]; // 这个字符在文件中出现的次数 long count; ...
- mariadb数据库基础知识及备份
数据库介绍 1.什么是数据库? 简单的说,数据库就是一个存放数据的仓库,这个仓库是按照一定的数据结构(数据结构是指数据的组织形式或数据之间的联系)来组织,存储的,我们可以通过数据库提供的多种方法来管理 ...
- UT源码+105032014018
设计佣金问题的程序 commission方法是用来计算销售佣金的需求,手机配件的销售商,手机配件有耳机(headphone).手机壳(Mobile phone shell).手机贴膜(Cellphon ...
- 洛谷 P4147 玉蟾宫 (最大子矩形问题)
这道题用到了悬线法,非常牛逼,可以看这个论文. https://blog.csdn.net/twtsa/article/details/8120269 #include<cstdio> # ...