P3379 【模板】最近公共祖先(LCA)(树链剖分)版
#include <bits/stdc++.h>
#define read read()
#define up(i,l,r) for(register int i = (l);i <= (r);i++)
#define down(i,l,r) for(register int i = (l);i >= (r);i--)
#define traversal_vedge(i) for(register int i = head[u]; i ;i = e[i].nxt)
#define ll long long
using namespace std;
int read
{
int x = , f = ; char ch = getchar();
while(ch < || ch > ) {if(ch == '-')f = -; ch = getchar();}
while(ch >= && ch <=) {x = * x + ch - ;ch = getchar();}
return x * f;
} int n,m,s;
const int N = ;
int dep[N],fa[N],size[N],top[N]; struct edge{
int v,nxt;
}e[N<<];int cnt,head[N];
void add(int u,int v){
e[++cnt] = (edge){v,head[u]};
head[u] = cnt;
} void readdata()
{
n = read; m = read; s = read;
up(i,,n-)
{
int u = read,v = read;
add(u,v);
add(v,u);
}
}
//-----------------------------------------------------------------------
void dfs(int u)
{
dep[u] = dep[fa[u]] + ;
size[u] = ;
top[u] = u;
//debug 未写 top[u] = u;
int heavyson_id = ,heavyson_size = ;
traversal_vedge(i)
{
int v = e[i].v;
if(v == fa[u]) continue;
fa[v] = u; //top[v] = u; //debug 不写top[v] = u;
dfs(v);
size[u] += size[v];
//heavyson = max(heavyson,size[v]);
if(size[v] > heavyson_size) heavyson_id = v,heavyson_size = size[v];
}
if(heavyson_id) top[heavyson_id] = u;//debug heavyson_id -> u;
//有重儿子才更新top[]
//dfs后,top[]只相当于重链上的fa[] //调用find(u)过后,从u到链首的所有top[]才指向链首;
} int find(int u)
{
if(u == top[u]) return u;
top[u] = find(top[u]);//debug top[u] -> u
return top[u];
//逆向搜索,并修改值;
} int lca(int x,int y)
{
if(find(x) != find(y)) //如果不在一条链上
//**一条链:重链为一条链,轻链单独一条边为一条链;
{
if(dep[top[x]] > dep[top[y]]) return lca(fa[top[x]] , y);//debug fa[top[x]] -> fa[dep[top[x]]];
else return lca(x , fa[top[y]]);
}
return dep[x] > dep[y] ? y : x;
} void work()
{
dfs(s);
while(m--)
{
int a = read,b = read;
printf("%d\n",lca(a,b));
}
} int main()
{
freopen("input.txt","r",stdin);
readdata();
work();
return ;
}
总结:
树链剖分版的LCA的dfs1稍有不同,不需要用数组记录每个点的重儿子;
树链剖分维护7个数组,树链剖分——LCA维护4个数组(fa[],dep[],size[],top[])son[]简化成heavyson_id
P3379 【模板】最近公共祖先(LCA)(树链剖分)版的更多相关文章
- jzoj4918. 【GDOI2017模拟12.9】最近公共祖先 (树链剖分+线段树)
题面 题解 首先,点变黑的过程是不可逆的,黑化了就再也洗不白了 其次,对于\(v\)的祖先\(rt\),\(rt\)能用来更新答案当且仅当\(sz_{rt}>sz_{x}\),其中\(sz\)表 ...
- Count on a tree SPOJ 10628 主席树+LCA(树链剖分实现)(两种存图方式)
Count on a tree SPOJ 10628 主席树+LCA(树链剖分实现)(两种存图方式) 题外话,这是我第40篇随笔,纪念一下.<( ̄︶ ̄)↗[GO!] 题意 是说有棵树,每个节点上 ...
- [BZOJ3626] [LNOI2014]LCA(树链剖分)
[BZOJ3626] [LNOI2014]LCA(树链剖分) 题面 给出一棵N个点的树,要求支持Q次询问,每次询问一个点z与编号为区间[l,r]内的点分别求最近公共祖先得到的最近公共祖先深度和.N, ...
- [模板] 最近公共祖先/lca
简介 最近公共祖先 \(lca(a,b)\) 指的是a到根的路径和b到n的路径的深度最大的公共点. 定理. 以 \(r\) 为根的树上的路径 \((a,b) = (r,a) + (r,b) - 2 * ...
- LCA树链剖分
LCA(Lowest Common Ancestor 最近公共祖先)定义如下:在一棵树中两个节点的LCA为这两个节点所有的公共祖先中深度最大的节点. 比如这棵树 结点5和6的LCA是2,12和7的LC ...
- BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]
3626: [LNOI2014]LCA Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2050 Solved: 817[Submit][Status ...
- BZOJ 3626: [LNOI2014]LCA( 树链剖分 + 离线 )
说多了都是泪啊...调了这么久.. 离线可以搞 , 树链剖分就OK了... -------------------------------------------------------------- ...
- BZOJ3626[LNOI2014]LCA——树链剖分+线段树
题目描述 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1.设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先.有q次询问,每次询 ...
- bzoj 3626 : [LNOI2014]LCA (树链剖分+线段树)
Description 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1.设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先.有q ...
随机推荐
- systemverilog的高亮显示
1. 在_vimrc文件末尾添加: syntax on "确定vim打开语法高亮 filetype on "打开文件类型检测 filetype plugin on "为特 ...
- 手把手教你如何用 OpenCV + Python 实现人脸识别
下午的时候,配好了OpenCV的Python环境,OpenCV的Python环境搭建.于是迫不及待的想体验一下opencv的人脸识别,如下文. 必备知识 Haar-like 通俗的来讲,就是作为人脸特 ...
- 用python探索和分析网络数据
Edited by Markdown Refered from: John Ladd, Jessica Otis, Christopher N. Warren, and Scott Weingart, ...
- py库: arrow (时间)
arrow是个时间日期库,简洁易用.支持python3.6 https://arrow.readthedocs.io/en/latest/ arrow官网api https://github.com/ ...
- C#设计模式(1)——单例模式(Singleton)
单例模式即所谓的一个类只能有一个实例, 也就是类只能在内部实例一次,然后提供这一实例,外部无法对此类实例化. 单例模式的特点: 1.只能有一个实例: 2.只能自己创建自己的唯一实例: 3.必须给所有其 ...
- C++ 日志生成 DLL
示例: #define log_dbg(format,args...) \ printf("[DBG] [%s: %s() line:%d]: "format ,__ ...
- 尚硅谷springboot学习25-嵌入式Servlet容器
SpringBoot默认使用Tomcat作为嵌入式的Servlet容器:
- week06 12 我们准备数据 前端调用rpc 前后端联调一下
用postman发送请求 出现一个问题 我在return结果前 要将数据转换成字典 所以我们用json.dumps()后再json.load()回来 这样就避免了这个问题 因为数据结构的数据 比如li ...
- 9. Palindrome Number (JAVA)
Determine whether an integer is a palindrome. An integer is a palindrome when it reads the same back ...
- PC滚动条样式
#jmwin2为外部容器 #jmwin2{ width: 90%; height: 65%; background: white; position: abso ...