洛谷 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

相关文章

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

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

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

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

Python中Flask模板的使用与高级技巧详解

《Python中Flask模板的使用与高级技巧详解》在Web开发中,直接将HTML代码写在Python文件中会导致诸多问题,Flask内置了Jinja2模板引擎,完美解决了这些问题,下面我们就来看看F... 目录一、模板渲染基础1.1 为什么需要模板引擎1.2 第一个模板渲染示例1.3 模板渲染原理二、模板

利用Python打造一个Excel记账模板

《利用Python打造一个Excel记账模板》这篇文章主要为大家详细介绍了如何使用Python打造一个超实用的Excel记账模板,可以帮助大家高效管理财务,迈向财富自由之路,感兴趣的小伙伴快跟随小编一... 目录设置预算百分比超支标红预警记账模板功能介绍基础记账预算管理可视化分析摸鱼时间理财法碎片时间利用财

如何在 Spring Boot 中实现 FreeMarker 模板

《如何在SpringBoot中实现FreeMarker模板》FreeMarker是一种功能强大、轻量级的模板引擎,用于在Java应用中生成动态文本输出(如HTML、XML、邮件内容等),本文... 目录什么是 FreeMarker 模板?在 Spring Boot 中实现 FreeMarker 模板1. 环

Android实现在线预览office文档的示例详解

《Android实现在线预览office文档的示例详解》在移动端展示在线Office文档(如Word、Excel、PPT)是一项常见需求,这篇文章为大家重点介绍了两种方案的实现方法,希望对大家有一定的... 目录一、项目概述二、相关技术知识三、实现思路3.1 方案一:WebView + Office Onl

IDEA自动生成注释模板的配置教程

《IDEA自动生成注释模板的配置教程》本文介绍了如何在IntelliJIDEA中配置类和方法的注释模板,包括自动生成项目名称、包名、日期和时间等内容,以及如何定制参数和返回值的注释格式,需要的朋友可以... 目录项目场景配置方法类注释模板定义类开头的注释步骤类注释效果方法注释模板定义方法开头的注释步骤方法注

JS+HTML实现在线图片水印添加工具

《JS+HTML实现在线图片水印添加工具》在社交媒体和内容创作日益频繁的今天,如何保护原创内容、展示品牌身份成了一个不得不面对的问题,本文将实现一个完全基于HTML+CSS构建的现代化图片水印在线工具... 目录概述功能亮点使用方法技术解析延伸思考运行效果项目源码下载总结概述在社交媒体和内容创作日益频繁的

C++中函数模板与类模板的简单使用及区别介绍

《C++中函数模板与类模板的简单使用及区别介绍》这篇文章介绍了C++中的模板机制,包括函数模板和类模板的概念、语法和实际应用,函数模板通过类型参数实现泛型操作,而类模板允许创建可处理多种数据类型的类,... 目录一、函数模板定义语法真实示例二、类模板三、关键区别四、注意事项 ‌在C++中,模板是实现泛型编程

MySQL使用binlog2sql工具实现在线恢复数据功能

《MySQL使用binlog2sql工具实现在线恢复数据功能》binlog2sql是大众点评开源的一款用于解析MySQLbinlog的工具,根据不同选项,可以得到原始SQL、回滚SQL等,下面我们就来... 目录背景目标步骤准备工作恢复数据结果验证结论背景生产数据库执行 SQL 脚本,一般会经过正规的审批