tarjan求LCA

news/2024/11/13 14:54:08/文章来源:https://www.cnblogs.com/pengdave/p/18379357

题面

如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先。

思路

这次我们要使用的知识点是 \(dfs\) 和并查集,这个 \(tarjan\) 是离线的,我们要先把每个点的每一个要跟它求 \(LCA\) 的点给记录下来,接下来用 \(dfs\) 跑这么个流程:

  1. 遍历这个点的每个子结点并进入子节点
  2. 将子节点与自己合并
  3. 遍历要跟它求 \(LCA\) 的点,如果这个点被访问了,这个点在并查集中的祖先便是答案

等等,你是不是蒙圈了?我们先放张图:

假设我们要求 \(LCA(3,6)\)

我们在这张图上模拟一下并查集中的过程:

首先,一切还是一盘散沙:

接下来,\(3\) 和它的父节点 \(4\) 合并起来了,由于与 \(3\) 它相关联的 \(6\) 还没访问,此时无法更新任何答案:

接着又是 \(5,4\) 以及 \(2,5\),都无法更新答案:

注意了!!!此处敲黑板!!!此时我们访问到 \(2\) 的另一个子节点 \(6\),此时我们便发现,\(3\) 已被访问,于是答案是 \(2\) !!!

后面的无用功就不放了。

于是,我们就发现了,其实我们就是把点按 \(dfn\) 序不断合并,当两个点要合并在一起时,此时的祖先便是答案,就像这样:

\(x\)\(y\) 便是要求 \(LCA\) 的两个点,它们现在刚好就合并到一起,显然只有到它们的公共祖先它们才会合并在一起,再由于回溯时是从深到低,所以第一次合并在一起时一定是到 \(LCA\) 了。

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdio>
#include<string>
#include<iomanip>
using namespace std;
const int N=5e5+10;
int n,m,s;
struct edge{int to,nxt;
}g[N<<1];
int head[N],tot1=0;
struct qry{int to,nxt,idx;
}q[N<<1];
int qhead[N],tot2=0;
int ans[N];
void add(int x,int y){tot1++;g[tot1].to=y;g[tot1].nxt=head[x];head[x]=tot1;return;
}
void qadd(int x,int y,int z){tot2++;q[tot2].to=y;q[tot2].nxt=qhead[x];q[tot2].idx=z;qhead[x]=tot2;return;
}
int fa[N],vis[N];
int Find(int x){return (fa[x]==x)?x:(fa[x]=Find(fa[x]));
}
void dfs(int u,int f){vis[u]=1;for(int i=head[u];i;i=g[i].nxt){int v=g[i].to;if(v!=f){dfs(v,u);fa[v]=u;}}for(int i=qhead[u];i;i=q[i].nxt){int v=q[i].to;if(vis[v]){ans[q[i].idx]=Find(v);}}return;
}
int main(){cin.tie(0);ios::sync_with_stdio(false);cin>>n>>m>>s;for(int i=1;i<n;i++){int u,v;cin>>u>>v;add(u,v);add(v,u);}for(int i=1;i<=m;i++){int u,v;cin>>u>>v;qadd(u,v,i);qadd(v,u,i);}for(int i=1;i<=n;i++)fa[i]=i;dfs(s,0);for(int i=1;i<=m;i++){cout<<ans[i]<<"\n";}cout<<flush;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/787206.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

语言模型与神经网络

语言模型与神经网络 语言模型(Language Model) Chat GPT 流畅的语言生成能力 自然语言是一种上下文相关的信息表达和信息传递方式。 定义:语言模型是衡量一句话出现在自然语言中的概率的模型。数学形式上,给定一句话 \(s=\{w_1,\dots,w_n\}\) ,它对应的概率为: \[\begin{…

春秋云镜 网鼎杯2022半决赛

春秋云镜 网鼎杯2022半决赛现用fscan扫一下访问发现是个wordpress,wpscan一下版本为6.2.6,使用了twentytwentyone theme 后台弱密码admin/123456登录 由于存在theme file editor,因此可以写马 随便找一个php文件,写入木马.使用蚁剑连接,路径之前wpscan给出来了.得到了第一个fla…

Windows提权方式汇总

windows 提权 一、土豆(potato)家族提权 原理 土豆提权就是通过 windows 的 COM(Component Object Model,组件对象模型)类。向指定的服务器端口发送 NTLM 认证,捕获认证数据包,并修改数据包内容使其认证成功,从而获得 system 权限的 token。在通过高权限的令牌执行反弹…

AxureRP原型图软件常见报错问题汇总

做Axure教程有一段时间了, 很多小伙伴在使用软件的时候就遇到很多问题,甚至还有在初始安装软件的时候就困难重重。这篇文章在你使用Axure软件过程中绝对可以用得到,赶紧点赞收藏起来~本期我们分为软件安装、和软件使用问题。本期只分享一些高频问题,如果你还遇到什么别的奇…

Triangle: The Data Structure(优秀の二维 ST 表)

link. 这种 RMQ 对像我这样萌新来说只有两种比较直观的方案:线段树 ST 表首先考虑线段树,如果是朴素的一维线段树,那么我们只能一行一行地扫,显然相比暴力优化了一些,但不多,最终还是会愉快地 T 掉(亲测)。 然后我不会超冷门的数据结构二维线段树。 所以蒟蒻只能用好写…

Python3.11二进制AI项目程序打包为苹果Mac App(DMG)-应用程序pyinstaller制作流程(AppleSilicon)

众所周知,苹果MacOs系统虽然贵为Unix内核系统,但由于系统不支持N卡,所以如果想在本地跑AI项目,还需要对相关的AI模块进行定制化操作,本次我们演示一下如何将基于Python3.11的AI项目程序打包为MacOS可以直接运行的DMG安装包,可以苹果系统中一键运行AI项目。 MacOs本地部署…

2.MapReduce论文总结

一. 介绍很多业务逻辑很简单,主要难点是数据量太大,可使用分布式处理提高速度。 传统分布式程序,计算逻辑和分布式任务分发、故障恢复混在一起,原本简单的计算逻辑变得模糊不清,难以处理。 MapReduce将两者分离,任务分发,容错,恢复等逻辑由模型完成,程序员只需要专注计…

Lab1 记录

一、非并行版本分析 1.非并行版本MapReduce流程通过第一个参数,传入Map和Reduce 函数 之后的参数为待处理文件名 读取文件 调用Map函数,对文件内容进行处理,生成KV对 对KV对进行sort 按照Key进行分组,然后对每组数据调用Reduce 将结果写入文件二、Lab思路 概述:Worker向Co…

JMeter:性能测试利器全解析

目录JMeter:性能测试利器全解析一、JMeter 的基础概念(一)什么是 JMeter(二)主要功能特点二、使用 JMeter 测试 Web 应用的步骤(一)安装与启动(二)创建测试计划(三)配置 Web 应用测试场景(四)运行测试(五)分析测试结果三、案例分析(一)案例背景(二)测试步骤…

ZBlogPHP迁移网站错误提示:Permission denied(请确保你的网站有写入权限777)

解决方案:设置你的网站目录为777 写入权限即可【注意:如果755可能会不行,最好直接使用777搞定】扫码添加技术【解决问题】专注中小企业网站建设、网站安全12年。熟悉各种CMS,精通PHP+MYSQL、HTML5、CSS3、Javascript等。承接:企业仿站、网站修改、网站改版、BUG修复、问题…