基本思想

把要求的点对保存下来,在dfs时顺带求出来。

方法

将每个已经遍历的点指向它回溯的最高节点(遍历它的子树时指向自己),
每遍历到一个点就处理它存在的询问
如果另一个点已经遍历,则lca就是另一个点指向的点。否则跳过

例如在下图中询问4,5和4,3的lca,遍历顺序为1,2,4,5,3

遍历到4时,各个点的指向如图

处理询问4,5和4,3。发现3和5没有遍历,跳过

回溯到3,然后遍历5。

发现4遍历过了,4,5的lca为2

然后回溯到1,遍历3

发现4遍历过了,4,3的lca为1

具体每个点的指向可以用并查集实现,每个询问可以用邻接表存储

具体实现

P3379 【模板】最近公共祖先(LCA)

#include<cstdio>
#define maxn 500005
struct Edge{
int next,to;
}edge[maxn*],q[maxn*];
int n,m,fi[maxn],se,qi[maxn],sq=,find[maxn],lca[maxn];
bool vis[maxn];
inline void add_edge(int u,int v){
edge[++se].next=fi[u],edge[se].to=v,fi[u]=se,
edge[++se].next=fi[v],edge[se].to=u,fi[v]=se;
}
inline void add_q(int u,int v){
q[++sq].next=qi[u],q[sq].to=v,qi[u]=sq,
q[++sq].next=qi[v],q[sq].to=u,qi[v]=sq;
}
int search(int x){//查找x指向的节点
if(find[x]==x)return x;
return find[x]=search(find[x]);
}
void Tarjan(int x,int f){//Tarjan求LCA
find[x]=x,vis[x]=;//当前节点已经遍历,并指向自己
for(int i=fi[x];i;i=edge[i].next){
int v=edge[i].to;
if(v==f)continue;
Tarjan(v,x);
}
for(int i=qi[x];i;i=q[i].next){
int v=q[i].to;
if(vis[v])lca[i>>]=search(v);//如果询问的另一个点已经遍历过,则LCA=search(v)
}
find[x]=f;//当前节点及子树指向父亲
}
int main(){
int u,v,s;
scanf("%d%d%d",&n,&m,&s);
for(int i=;i<n;i++){
scanf("%d%d",&u,&v);
add_edge(u,v);
}
for(int i=;i<m;i++){
scanf("%d%d",&u,&v);
add_q(u,v);//将询问用邻接表存储
}
Tarjan(s,);
for(int i=;i<=m;i++)printf("%d\n",lca[i]);
return ;
}

最新文章

  1. iso网络各层协议
  2. nopcommerce之权限模块
  3. 如何在word里面插入目录
  4. java之其它命令
  5. ASP.NET服务器控件OnClientClick事件中Eval()作为js方法的参数的一种写法
  6. html5常用英语单词
  7. Cannot create an instance of OLE DB provider “OraOLEDB.Oracle” for linked server &quot;xxxxxxx&quot;.
  8. DownEditTextView【自定义Edittext对Android 软键盘向下的监听】
  9. win2012服务器配置ftp
  10. Hishop数据库根据产品ProductID取产品规格
  11. Redis-01.初探
  12. 一篇文章读懂HTTPS及其背后的加密原理
  13. Java线程池ThreadPoolExecutor使用和分析(一)
  14. C# Form Chart X刻度左右多余一格怎么去掉
  15. 转://使用showplan.sql分析sql Performance
  16. metamask-mascara-在线钱包使用
  17. Gson的fromJson()方法把json字符创转为实体
  18. Servlet API
  19. Java代码质量度量工具大阅兵
  20. aarch64_fc26_url

热门文章

  1. HTML中使用js的三种方式及优缺点介绍
  2. mac下Spark的安装与使用
  3. Python全栈开发:线程、进程和协程
  4. 使用JS实现页面中动态添加文件上传输入项
  5. leetcode-129-求根到叶子结点数字之和
  6. 廖雪峰Java12maven基础-2maven进阶-2模块管理
  7. hdu 5382
  8. ES6数组对象新增方法
  9. wiki方法能在H5页面上
  10. vue alert插件(标题为图片)(自写)