洛谷 P3379 【模板】最近公共祖先(LCA) (在线倍增+离线Tarjan)

2023-10-05 23:31

本文主要是介绍洛谷 P3379 【模板】最近公共祖先(LCA) (在线倍增+离线Tarjan),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目描述

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

输入格式:

第一行包含三个正整数N、M、S,分别表示树的结点个数、询问的个数和树根结点的序号。

接下来N-1行每行包含两个正整数x、y,表示x结点和y结点之间有一条直接连接的边(数据保证可以构成树)。

接下来M行每行包含两个正整数a、b,表示询问a结点和b结点的最近公共祖先。

输出格式:

输出包含M行,每行包含一个正整数,依次为每一个询问的结果。

输入样例#1:

5 5 4
3 1
2 4
5 1
1 4
2 4
3 2
3 5
1 2
4 5

输出样例#1:

4
4
1
4
4

思路

题如其名,就是lca的模板。我就存一存我的lca模板~

离线Tarjan

#include <cstdio>
#include <cstring>
#include <cctype>
#include <stdlib.h>
#include <string>
#include <map>
#include <iostream>
#include <stack>
#include <cmath>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
#define inf 1000000
#define mem(a,b) memset(a,b,sizeof(a))
const int N=500000+7;
int pre[N],first[N],first2[N],tot,tot2;
bool vis[N];//标记有没有询问
int n;
struct edge
{int v,next;
} e[2*N];
struct Query
{int v,w,next;
} query[2*N];void add_edge(int u,int v)
{e[tot].v=v;e[tot].next=first[u];first[u]=tot++;
}void add_query(int u,int v)
{query[tot2].v=v;query[tot2].w=-1;query[tot2].next=first2[u];first2[u]=tot2++;
}int find(int x)
{return x==pre[x]?x:pre[x]=find(pre[x]);
}int lca(int u,int fa)
{for(int i=first[u]; ~i; i=e[i].next){int v=e[i].v;if(v==fa) continue;lca(v,u);pre[v]=u;}vis[u]=1;for(int i=first2[u]; ~i; i=query[i].next){int v=query[i].v;if(vis[v])query[i].w=find(v);}
}void init()
{mem(first,-1);mem(first2,-1);mem(vis,0);tot=0;tot2=0;for(int i=1; i<=n; i++)pre[i]=i;
}int main()
{int m,s,u,v;scanf("%d%d%d",&n,&m,&s);init();for(int i=1; i<n; i++){scanf("%d%d",&u,&v);add_edge(u,v);add_edge(v,u);}for(int i=1; i<=m; i++){scanf("%d%d",&u,&v);add_query(u,v);add_query(v,u);}lca(s,pre[s]);for(int i=0; i<tot2; i++)if(query[i].w!=-1)printf("%d\n",query[i].w);return 0;
}

在线倍增

#include <cstdio>
#include <cstring>
#include <cctype>
#include <stdlib.h>
#include <string>
#include <map>
#include <iostream>
#include <stack>
#include <cmath>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
#define inf 1000000
#define mem(a,b) memset(a,b,sizeof(a))
const int N=500000+7;int n,m,s;
int tot;
int first[N],d[N],p[N][21];struct edge
{int v,next;
} e[2*N];void add_edge(int u,int v)
{e[tot].v=v;e[tot].next=first[u];first[u]=tot++;
}void dfs(int u,int fa)
{d[u]=d[fa]+1;p[u][0]=fa;for(int i=1; (1<<i)<=d[u]; i++)p[u][i]=p[p[u][i-1]][i-1];for(int i=first[u]; ~i; i=e[i].next){int v=e[i].v;if(v!=fa)dfs(v,u);}
}int lca(int a,int b)
{if(d[a]>d[b]) swap(a,b);//保证a在b点的上方for(int i=20; i>=0; i--)if(d[a]<=d[b]-(1<<i))b=p[b][i];  //把b移到和a同一个深度if(a==b) return a;for(int i=20; i>=0; i--){if(p[a][i]==p[b][i])continue;elsea=p[a][i],b=p[b][i];//一起向上跳跃}return p[a][0];
}void init()
{tot=0;mem(first,-1);mem(d,0);mem(p,0);
}
int main()
{init();int a,b;scanf("%d%d%d",&n,&m,&s);for(int i=1; i<n; i++){scanf("%d%d",&a,&b);add_edge(a,b);add_edge(b,a);}dfs(s,0);for(int i=1; i<=m; i++){scanf("%d%d",&a,&b);printf("%d\n",lca(a,b));}return 0;
}

这篇关于洛谷 P3379 【模板】最近公共祖先(LCA) (在线倍增+离线Tarjan)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/152284

相关文章

使用Java填充Word模板的操作指南

《使用Java填充Word模板的操作指南》本文介绍了Java填充Word模板的实现方法,包括文本、列表和复选框的填充,首先通过Word域功能设置模板变量,然后使用poi-tl、aspose-words... 目录前言一、设置word模板普通字段列表字段复选框二、代码1. 引入POM2. 模板放入项目3.代码

nodejs打包作为公共包使用的完整流程

《nodejs打包作为公共包使用的完整流程》在Node.js项目中,打包和部署是发布应用的关键步骤,:本文主要介绍nodejs打包作为公共包使用的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言一、前置准备二、创建与编码三、一键构建四、本地“白嫖”测试(可选)五、发布公共包六、常见踩坑提醒

Python进行word模板内容替换的实现示例

《Python进行word模板内容替换的实现示例》本文介绍了使用Python自动化处理Word模板文档的常用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友... 目录技术背景与需求场景核心工具库介绍1.获取你的word模板内容2.正常文本内容的替换3.表格内容的

在Android中使用WebView在线查看PDF文件的方法示例

《在Android中使用WebView在线查看PDF文件的方法示例》在Android应用开发中,有时我们需要在客户端展示PDF文件,以便用户可以阅读或交互,:本文主要介绍在Android中使用We... 目录简介:1. WebView组件介绍2. 在androidManifest.XML中添加Interne

kkFileView在线预览office的常见问题以及解决方案

《kkFileView在线预览office的常见问题以及解决方案》kkFileView在线预览Office常见问题包括base64编码配置、Office组件安装、乱码处理及水印添加,解决方案涉及版本适... 目录kkFileView在线预览office的常见问题1.base642.提示找不到OFFICE组件

Linux下在线安装启动VNC教程

《Linux下在线安装启动VNC教程》本文指导在CentOS7上在线安装VNC,包含安装、配置密码、启动/停止、清理重启步骤及注意事项,强调需安装VNC桌面以避免黑屏,并解决端口冲突和目录权限问题... 目录描述安装VNC安装 VNC 桌面可能遇到的问题总结描js述linux中的VNC就类似于Window

SpringBoot集成EasyPoi实现Excel模板导出成PDF文件

《SpringBoot集成EasyPoi实现Excel模板导出成PDF文件》在日常工作中,我们经常需要将数据导出成Excel表格或PDF文件,本文将介绍如何在SpringBoot项目中集成EasyPo... 目录前言摘要简介源代码解析应用场景案例优缺点分析类代码方法介绍测试用例小结前言在日常工作中,我们经

Linux在线解压jar包的实现方式

《Linux在线解压jar包的实现方式》:本文主要介绍Linux在线解压jar包的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux在线解压jar包解压 jar包的步骤总结Linux在线解压jar包在 Centos 中解压 jar 包可以使用 u

基于Python实现一个简单的题库与在线考试系统

《基于Python实现一个简单的题库与在线考试系统》在当今信息化教育时代,在线学习与考试系统已成为教育技术领域的重要组成部分,本文就来介绍一下如何使用Python和PyQt5框架开发一个名为白泽题库系... 目录概述功能特点界面展示系统架构设计类结构图Excel题库填写格式模板题库题目填写格式表核心数据结构

Java如何根据word模板导出数据

《Java如何根据word模板导出数据》这篇文章主要为大家详细介绍了Java如何实现根据word模板导出数据,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... pom.XML文件导入依赖 <dependency> <groupId>cn.afterturn</groupId>