LCA(Tarjan)
时间复杂度:dfs为O(N),dfs过程中处理所有查询对为O(M),总时间复杂度O(N+M)
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=500010, maxm=500010;
int N, M, S, tot, h[maxn], v[maxn], fa[maxn], p_tot, p_h[maxn];
struct edge{ int t, nxt; }E[maxn<<1]; //链式前向星,用于存储树
void add_edge(int u, int v){ E[++tot].t=v; E[tot].nxt=h[u]; h[u]=tot; }
struct pair{ int s, t, lca, nxt;}P[maxm<<1]; //链式前向星,用于存储查询对
void add_pair(int s, int t){ P[++p_tot].t=t; P[p_tot].s=s; P[p_tot].nxt=p_h[s]; p_h[s]=p_tot; }
inline int read()
{
int s=0, w=1; char ch=getchar();
while(ch<='0' || ch>'9') { if(ch=='-') w=-1; ch=getchar(); }
while(ch>='0' && ch<='9'){ s=s*10+ch-'0'; ch=getchar(); }
return s*w;
}
int getfa(int k){ return fa[k]==k ? k : fa[k]=getfa(fa[k]); } //并查集的查询,带路径压缩
void lca_tarjan(int x)
{
v[x]=1, fa[x]=x; //x点已访问,设置其fa为自己,形成以x为根的一颗独立子树
for(int i=h[x]; i; i=E[i].nxt)
if(!v[E[i].t]) lca_tarjan(E[i].t), fa[E[i].t]=x; //递归结束后再建立x与x儿子的父子关系
for(int i=p_h[x], y; i; i=P[i].nxt) //查找与x有关的所有lca询问
if(v[y=P[i].t]){ //对于某个询问(x, y),如果y已经访问过了,lca(x, y)=getfa(y)
P[i].lca=getfa(y);
if(i%2) P[i+1].lca=P[i].lca; //P数组中pair是成对存入的,一个是(x, y), 一个是(y, x)
else P[i-1].lca=P[i].lca;
}
}
int main(){
N=read(); M=read(); S=read();
for(int i=1, x, y; i<N; i++){ x=read(); y=read(); add_edge(x, y); add_edge(y, x); }
for(int i=1, a, b; i<=M; i++){ a=read(); b=read(); add_pair(a, b); add_pair(b, a); }
lca_tarjan(S);
for(int i=1; i<=p_tot; i++)
if(i%2) printf("%d\n", P[i].lca);
return 0;
}
LCA(Tarjan)的更多相关文章
- HDU 2874 Connections between cities(LCA Tarjan)
Connections between cities [题目链接]Connections between cities [题目类型]LCA Tarjan &题意: 输入一个森林,总节点不超过N ...
- POJ 1986 Distance Queries(LCA Tarjan法)
Distance Queries [题目链接]Distance Queries [题目类型]LCA Tarjan法 &题意: 输入n和m,表示n个点m条边,下面m行是边的信息,两端点和权,后面 ...
- LCA Tarjan方法
LCA Tarjan方法 不得不说,高中生好厉害,OI大佬,感觉上个大学好憋屈啊! 说多了都是眼泪 链接拿去:http://www.cnblogs.com/JVxie/p/4854719.html
- LCA tarjan+并查集POJ1470
LCA tarjan+并查集POJ1470 https://www.cnblogs.com/JVxie/p/4854719.html 不错的一篇博客啊,让我觉得LCA这么高大上的算法不是很难啊,嘻嘻嘻 ...
- hihoCoder #1067 : 最近公共祖先·二 [ 离线LCA tarjan ]
传送门: #1067 : 最近公共祖先·二 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上上回说到,小Hi和小Ho用非常拙劣——或者说粗糙的手段山寨出了一个神奇的网站 ...
- LA 5061 LCA tarjan 算法
题目大意: 给定所有点的权值都为0,给定一棵树以后,每次询问都要求给定两点 x , y 和一个权值w,要求x,y路径上所有点权值加上w,最后求出每一个节点的值 这里因为查询和点都特别多,所以希望能最后 ...
- [CF 191C]Fools and Roads[LCA Tarjan算法][LCA 与 RMQ问题的转化][LCA ST算法]
参考: 1. 郭华阳 - 算法合集之<RMQ与LCA问题>. 讲得很清楚! 2. http://www.cnblogs.com/lazycal/archive/2012/08/11/263 ...
- 最近公共祖先LCA(Tarjan算法)的思考和算法实现
LCA 最近公共祖先 Tarjan(离线)算法的基本思路及其算法实现 小广告:METO CODE 安溪一中信息学在线评测系统(OJ) //由于这是第一篇博客..有点瑕疵...比如我把false写成了f ...
- POJ 1330 Nearest Common Ancestors(LCA Tarjan算法)
题目链接:http://poj.org/problem?id=1330 题意:给定一个n个节点的有根树,以及树中的两个节点u,v,求u,v的最近公共祖先. 数据范围:n [2, 10000] 思路:从 ...
- Network POJ - 3694 (LCA+tarjan+桥)
题目链接:https://vjudge.net/problem/POJ-3694 具体思路:首先可以通过缩点的方式将整个图变成一个树,并且树的每条边是桥,但是我们可以利用dfn数组将整个图变成树,这样 ...
随机推荐
- MFC桌面电子时钟的设计与实现
目录 核心技术 需求分析 程序设计 程序展示 (一)核心技术 MFC(Micosoft Foundation Class Libay,微基础类库)是微基于Windows平台下的C++类库集合,MFC包 ...
- 数据库【mysql】之pymysql
安装模块 pip install pymysql 导入模块 import pymysql 创建链接 conn = pymysql.connect(host=') 创建索引 cursor = conn. ...
- python之sqlalchemy的使用
准备数据 from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column from sqla ...
- 3.15 总结,初始java
- python之面相对象进阶
一 isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 class Foo(object) ...
- mybatis 错误
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.TooManyR ...
- .NET Core 实现 Redis 批量查询指定格式的Key
一. 问题场景 Redis 作为当前最流行的内存型 NoSQL 数据库,被许多公司所使用,作为分布式缓存.我们在实际使用中一般都会为 key 带上指定的前缀或者其他定义的格式.当由于我们程序出现bug ...
- 循环语句之for循环
什么是循环语句? 循环语句可以在满足循环条件的情况下,反复执行某一段代码,这段被重复执行的代码被称为循环体语句,当反复执行这个循环体时,需要在合适的时候把循环判断条件修改为false,从而结束循环,否 ...
- java常识
什么是java语言? java语言是美国Sun公司,在1995年推出的高级编程语言.所谓编程语言,是计算机的语言,人们可以使用编程语言对计算机下达命令,让计算机完成人们需要的功能. java语言发展历 ...
- day01(计算机组成,进制,内存分布,操作系统)
本周内容: 第一天: 计算机原理 操作系统 第二天: 编程语言 python入门:环境 - 编辑器 变量 基本数据类型 学习方法: 鸡汤 - 干货 wwwh : what | why | where ...