#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)(树链剖分)版的更多相关文章

  1. jzoj4918. 【GDOI2017模拟12.9】最近公共祖先 (树链剖分+线段树)

    题面 题解 首先,点变黑的过程是不可逆的,黑化了就再也洗不白了 其次,对于\(v\)的祖先\(rt\),\(rt\)能用来更新答案当且仅当\(sz_{rt}>sz_{x}\),其中\(sz\)表 ...

  2. Count on a tree SPOJ 10628 主席树+LCA(树链剖分实现)(两种存图方式)

    Count on a tree SPOJ 10628 主席树+LCA(树链剖分实现)(两种存图方式) 题外话,这是我第40篇随笔,纪念一下.<( ̄︶ ̄)↗[GO!] 题意 是说有棵树,每个节点上 ...

  3. [BZOJ3626] [LNOI2014]LCA(树链剖分)

    [BZOJ3626] [LNOI2014]LCA(树链剖分) 题面 给出一棵N个点的树,要求支持Q次询问,每次询问一个点z与编号为区间[l,r]内的点分别求最近公共祖先得到的最近公共祖先深度和.N, ...

  4. [模板] 最近公共祖先/lca

    简介 最近公共祖先 \(lca(a,b)\) 指的是a到根的路径和b到n的路径的深度最大的公共点. 定理. 以 \(r\) 为根的树上的路径 \((a,b) = (r,a) + (r,b) - 2 * ...

  5. LCA树链剖分

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

  6. BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2050  Solved: 817[Submit][Status ...

  7. BZOJ 3626: [LNOI2014]LCA( 树链剖分 + 离线 )

    说多了都是泪啊...调了这么久.. 离线可以搞 , 树链剖分就OK了... -------------------------------------------------------------- ...

  8. BZOJ3626[LNOI2014]LCA——树链剖分+线段树

    题目描述 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1.设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先.有q次询问,每次询 ...

  9. bzoj 3626 : [LNOI2014]LCA (树链剖分+线段树)

    Description 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1.设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先.有q ...

随机推荐

  1. go语言学习--处理map的无序输出

    最近工作中遇到了这样的一个场景,需要处理一个无限极分类的问题,对于数据结构的定义首先想到了,map,map[int]map[int]struct.通过两层map的定义归类parent_id和id的关系 ...

  2. vue展示dicom文件,医疗系统。

    环境:vue.webpack.constone 资料来源及文件:https://github.com/GleasonBian/CornerstoneVueWADO 需要下载的模块:cornerston ...

  3. django之 F&Q 聚合与分组

    F 使用查询条件的值,专门取对象中某列值的操作,可以对同一个表中的两个列进行比较 from django.db.models import F ret=models.Book.objects.filt ...

  4. 浅谈Cookie与Session技术

      一.什么是状态管理 将客户端与服务器之间多次交互当做一个整体来看,并且将多次交互所涉及的数据(状态)保存下来. 会话:当用户打开浏览器,访问多个WEB资源,然后关闭浏览器的过程,称之为一个会话,选 ...

  5. 多线程之sleep和wait的区别

    它们最大本质的区别是:sleep()不释放同步锁,wait()释放同步锁. 还有用法的上的不同是:sleep(milliseconds)可以用时间指定来使他自动醒过来,如果时间不到你只能调用inter ...

  6. spring mvc 自动生成代码

    generator mybaits 详细配置: 目录结构 执行命令 OK git:https://gitee.com/xxoo0_297/generator.git

  7. Hive表种map字段的查询取用

    建表可以用 map<string,string> 查询时可以按照 aaa[bbb], aaa 是map字段名,bbb是其中的参数名,就可以取到这个参数的值了 当参数名bbb是string时 ...

  8. Python3 timeit的用法

    Python3中的timeit模块可以用来测试小段代码的运行时间 其中主要通过两个函数来实现:timeit和repeat,代码如下: def timeit(stmt="pass", ...

  9. 利用nginx添加账号密码验证

    server { listen ; server_name xxx.com; location / { proxy_pass http://10.10.10.10:5601; proxy_redire ...

  10. K8s之配置文件kubeconfig生成

    在开启了 TLS 的集群中,每当与集群交互的时候少不了的是身份认证,使用 kubeconfig(即证书) 和 token 两种认证方式是最简单也最通用的认证方式. 以kubectl为例介绍kubeco ...