tarjian求lca
看了好多dalao的博客,就总结一下啦ovo
tarjian算法很是神奇,它的作用是求lca。它是一种离线算法。
在线是指输入一个询问输出一个结果。
离线是将询问一次性输入,一起处理。
tarjan它是将m个询问打乱顺序,在每个结点上挂上它的询问,利用dfs和并查集进行处理。
对于一个结点u,如果要找(u,v)的lca,u和v的关系分为以下几种情况:
(1)结点v在u的子树中,那么lca(u,v)=u;
(2) 结点v不在u的子树中,那么v就在u子结点以外的结点中。v可能在u的爸爸的子树中,那么lca(u,v)=u的爸爸;
(3)如果v不在u的爸爸的子树中,那么v可能在u的爸爸的爸爸的子树中,lca(u,v)=u的爸爸的爸爸;
发现找爸爸的过程好像和并查集的操作很像哦.
【代码】
#include<bits/stdc++.h>
using namespace std;
#define N 10000
vector<int>vec[N];
vector<int>que[N];
int dad[N],far[N],qx[N],qy[N];
int n,m,x,y,ans[N];
int f(int x)
{
return far[x]==x?x:far[x]=f(far[x]);
}
void dfs(int x)
{
far[x]=x;
for(int i=;i<vec[x].size();i++)
{
if(dad[x]!=vec[x][i])
{
dad[vec[x][i]]=x;
dfs(vec[x][i]);
}
}
for(int i=;i<que[x].size();i++)
{
if(dad[y=qx[que[x][i]]^qy[que[x][i]]]^x)//y是x结点的一个询问;x^x^y=y;
{
ans[que[x][i]]=f(y);
}
}
far[x]=dad[x];
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
{
scanf("%d%d",&x,&y);
vec[x].push_back(y);
vec[y].push_back(x);
}
for(int i=;i<=m;i++)
{
scanf("%d%d",&qx[i],&qy[i]);
que[qx[i]].push_back(i);//在每个结点上挂上它的询问是第几个询问;
que[qy[i]].push_back(i);
}
dfs();
for(int i=;i<=m;i++)
{
printf("%d ",ans[i]);//每个询问的答案’
}
return ;
}
tarjian求lca的更多相关文章
- 【模板】Tarjian求LCA
概念 公共祖先,就是两个节点在这棵树上深度最大的公共的祖先节点 举个例子吧,如下图所示4和5的最近公共祖先是2,5和3的最近公共祖先是1,2和1的最近公共祖先是1. 算法 常用的求LCA的算法有:Ta ...
- 树链剖分求LCA
树链剖分中各种数组的作用: siz[]数组,用来保存以x为根的子树节点个数 top[]数组,用来保存当前节点的所在链的顶端节点 son[]数组,用来保存重儿子 dep[]数组,用来保存当前节点的深度 ...
- 树上倍增求LCA(最近公共祖先)
前几天做faebdc学长出的模拟题,第三题最后要倍增来优化,在学长的讲解下,尝试的学习和编了一下倍增求LCA(我能说我其他方法也大会吗?..) 倍增求LCA: father[i][j]表示节点i往上跳 ...
- [算法]树上倍增求LCA
LCA指的是最近公共祖先(Least Common Ancestors),如下图所示: 4和5的LCA就是2 那怎么求呢?最粗暴的方法就是先dfs一次,处理出每个点的深度 然后把深度更深的那一个点(4 ...
- 【树链剖分】洛谷P3379 树链剖分求LCA
题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...
- 【倍增】洛谷P3379 倍增求LCA
题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...
- 【RMQ】洛谷P3379 RMQ求LCA
题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...
- 【Tarjan】洛谷P3379 Tarjan求LCA
题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...
- 树上倍增求LCA及例题
先瞎扯几句 树上倍增的经典应用是求两个节点的LCA 当然它的作用不仅限于求LCA,还可以维护节点的很多信息 求LCA的方法除了倍增之外,还有树链剖分.离线tarjan ,这两种日后再讲(众人:其实是你 ...
随机推荐
- centOS6.2 最小安装下的无线网络配置
一.安装wireless_tools,http://www.linuxfromscratch.org/blfs/view/svn/basicnet/wireless_tools.html 二.vi / ...
- jquery 与javascript关系 ①取元素 ②操作内容 ③操作属性 ④操作 样式 ⑤ 事件 点击变色
jQuery的min版本和原版功能是一样的,min版主要应用于已经开发成的网页中,而非min版 的文件比较大,里面有整洁的代码书写规范和注释,主要应用于脚本开发过程当中. JQuery是继protot ...
- 【BZOJ1345】[Baltic2007]序列问题Sequence 贪心+单调栈
[BZOJ1345][Baltic2007]序列问题Sequence Description 对于一个给定的序列a1, …, an,我们对它进行一个操作reduce(i),该操作将数列中的元素ai和a ...
- 【BZOJ1778】[Usaco2010 Hol]Dotp 驱逐猪猡 期望DP+高斯消元
[BZOJ1778][Usaco2010 Hol]Dotp 驱逐猪猡 Description 奶牛们建立了一个随机化的臭气炸弹来驱逐猪猡.猪猡的文明包含1到N (2 <= N <= 300 ...
- 九度OJ 1203:IP地址 (字符串处理)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:3038 解决:1496 题目描述: 输入一个ip地址串,判断是否合法. 输入: 输入的第一行包括一个整数n(1<=n<=500) ...
- netbeans无法新建项目
在ubuntu上安装netbeans最新版(7.3.1),但是安装之后发现无法新建项目,一直提示请等待,google之后说是jdk的问题,查看了一下jdk的版本为1.6.试着安装了1.7版本的,问题解 ...
- MyBatis -- 一步步教你使用MyBatis
1.建立开发环境 1.1 创建项目,java项目或者javaweb项目均可,如图: 1.2 加入所须要的jar包到项目lib文件夹下 一个MyBatis-3.2.4.jar包 一个驱动包mysql ...
- oracle chain
[oracle@tyger dbs]$ sqlplus / as sysdba SQL*Plus: Release 10.2.0.1.0 - Production on Tue May 6 13:02 ...
- Android 主线程和子线程通信问题
Android 如今不支持View在子线程中创建及调用其方法.假设要实现子线程内容更新之后.将结果及时反馈到主线程中,该怎样出来呢? 能够在主线程中创建Handler来实现. 这样子线 ...
- xpath取最后一个元素
取xpath最后一个book元素 book[last()] 取xpath最后第二个book元素 book[last()-1]