LCA问题的ST,tarjan离线算法解法
一 ST算法与LCA
- 介绍
第一次算法笔记这样的东西,以前学算法只是笔上画画写写,理解了下,刷几道题,其实都没深入理解,以后遇到新的算法要把自己的理解想法写下来,方便日后回顾嘛>=<
RMQ问题就是询问一个给定数组相应区间i…j的最大值。
ST算法的思路是:f(i,j)表示i开始的2^j个数中最大值/最小值,通过运用dp的思想初始化f(i,j)求出每个i(1….n)出发长度为2^j(0<=j<=log(n)/log(2))最大值。
由于初始化过程复杂度只有O(nlog(n)),查询过程O(1),所以会比线段树快很多,而且更不容易出错。
以下为初始化代码:
Init:
for(int i = 1; i <= n; i++)
f(i, 0) = a[i];
for(int i = 1; i <= (int)log(n)/log(2); i++)
for(int j = 1; j + (1<<i) – 1 <= n; j++)
f(i, j) = max(f (i , j-1), f(i+(1<<(j-1) ), j - 1);
查询区间[a, b],先找到一个最大的值k = (int)log(b-a+1)/log(2);
然后分别查询左右两个端点出发的长度为2^k的区间最大值。
RMQ(a, b)
int k = (int)log(b-a+1)/log(2.0);
return max(f(a, k), f(b – (1<<k) + 1, k));
- 解决LCA问题
在dfs遍历过程中,每次进入或回溯到结点u时,将深度存入熟读dep[cnt],cnt表示在数组中的编号,同时用E[cnt]记录相应的结点即:E[cnt] = u, 并且用R数组记录初次访问u的时候,存进D数组的位置,即R[u] = cnt.
这样每次查询LCA(u,v) = E[RMQ(dep, R[u], R[v])], (R[u] < R[v]),RMQ返回到的是下标R[u]~R[v]的区间中深度最小的点在数组中的位置,也就是下标,这样通过E数组可获得该结点编号。
- dfs(u, d)
- R[u] = ++cnt
- dep[cnt] = d
- E[cnt] = u
- vis[u] = true
- for each (u, v) in TREE
- if !vis[v]
- dfs(v, d+1)
- dep[++cnt] = d
- E[cnt] = u
最后cnt 的大小为2*n-1,也就是每条边访问了2次。
最近遇到的一个问题是,HDU – 3686 Traffic Real Time Query System 对双连通分量缩点,使得割点和各个连通分量构成一个树形图,求这个树形图中任意两点之间路径最少需要经过多少个割点,稍有变化
只是在遇到割点时距离才增加,而且当LCA(u, v)是割点的时候需要把结果ans++。
题解: HDU Traffic Real Time Query System
二 tarjan离线算法解决LCA
主要是事先读入所有的查询,然后在dfs到u的过程中,看所有需要查询的(u,v)中另一点v是否已经访问过,如果是的话此时findset(v)便是u,v的LCA。
通过ans = dis[u] + dis[v] – 2 * dis[findset(v)]便可知道u,v间的最短距离。
常见的LCA问题就是求树形图中2个点的最短距离,3个点连接起来的最短距离,都是通过两两求出最短距离然后除以2(对于3个点的情况),是不是n个点的时候除以(n-1)?猜了一下,求高手证实、==
3个点:题解 ZOJ - 3195 Design the city。2个点的类似: HDU – 2586 How far away ?
tarjan离线解决HDU Traffic Real Time Query System 题解.
更详细的解释 博客 在这里了,遇到一个LCA的题目,就学习了一下,我只是做了一个新手搬运工hahaha~
、
LCA问题的ST,tarjan离线算法解法的更多相关文章
- LCA 最近公共祖先 Tarjan(离线)算法的基本思路及其算法实现
首先是最近公共祖先的概念(什么是最近公共祖先?): 在一棵没有环的树上,每个节点肯定有其父亲节点和祖先节点,而最近公共祖先,就是两个节点在这棵树上深度最大的公共的祖先节点. 换句话说,就是两个点在这棵 ...
- LCA最近公共祖先 Tarjan离线算法
学习博客: http://noalgo.info/476.html 讲的很清楚! 对于一颗树,dfs遍历时,先向下遍历,并且用并查集维护当前节点和父节点的集合.这样如果关于当前节点(A)的关联节点( ...
- LCA最近公共祖先(Tarjan离线算法)
这篇博客对Tarjan算法的原理和过程模拟的很详细. 转载大佬的博客https://www.cnblogs.com/JVxie/p/4854719.html 第二次更新,之前转载的博客虽然胜在详细,但 ...
- LCA(最近公共祖先)--tarjan离线算法 hdu 2586
HDU 2586 How far away ? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/ ...
- 最近公共祖先LCA Tarjan 离线算法
[简介] 解决LCA问题的Tarjan算法利用并查集在一次DFS(深度优先遍历)中完成所有询问.换句话说,要所有询问都读入后才开始计算,所以是一种离线的算法. [原理] 先来看这样一个性质:当两个节点 ...
- HDU-2586-How far away(LCA Tarjan离线算法)
链接:https://vjudge.net/problem/HDU-2586 题意: 勇气小镇是一个有着n个房屋的小镇,为什么把它叫做勇气小镇呢,这个故事就要从勇气小镇成立的那天说起了,修建小镇的时候 ...
- POJ 1330 Nearest Common Ancestors 【最近公共祖先LCA算法+Tarjan离线算法】
Nearest Common Ancestors Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 20715 Accept ...
- LCA 最近公共祖先 tarjan离线 总结 结合3个例题
在网上找了一些对tarjan算法解释较好的文章 并加入了自己的理解 LCA(Least Common Ancestor),顾名思义,是指在一棵树中,距离两个点最近的两者的公共节点.也就是说,在两个点通 ...
- HDU 2586 How far away ?(经典)(RMQ + 在线ST+ Tarjan离线) 【LCA】
<题目链接> 题目大意:给你一棵带有边权的树,然后进行q次查询,每次查询输出指定两个节点之间的距离. 解题分析:本题有多重解决方法,首先,可用最短路轻易求解.若只用LCA解决本题,也有三种 ...
随机推荐
- ThinkPHP的配置
ThinkPHP配置:conf目录下 'URL_PATHINFO_DEPR'=>'-',//修改URL的分隔符, 'TMPL_L_DELIM'=>'<{', //修改左定界符 'TM ...
- Python(2.7.6) 迭代器
除了对列表.集合和字典等进行迭代,还能对其他对象进行迭代:实现 __iter__ 方法的对象.例如, 文件对象就是可迭代的: >>> dir(file) ['__class__', ...
- Sublime Text2上搭建C/C++环境
环境:Sublime Text2 win7 64位 1.下载Sublime Text2并安装 下载地址:http://www.sublimetext.com/ 2.需要用 ...
- Java _Map接口的使用(转载)
转载自:http://blog.csdn.net/tomholmes7/article/details/2663379.转载请注明原作者地址 Map Map以按键/数值对的形式存储数据,和数组非常相似 ...
- (十一)Hibernate 高级配置
第一节:配置数据库连接池 反问数据库,需要不断的创建和释放连接,假如访问量大的话,效率比较低级,服务器消耗大: 使用数据库连接池,我们可以根据实际项目的情况,定义连接池的连接个数,从而可以实现从连接池 ...
- C# Linq简介
LInq是Language Integrated Query的简称,它是微软在.net framework 3.5里面新加入的特性,用以简化查询查询操作.它主要包含了3块,Linq to Object ...
- LPC17XX 数据手册摘要之系统时钟与功率控制
系统时钟与功率控制 一.系统时钟 LPC17XX有三个独立的时钟振荡器,分别是主振荡器(MIAN_OSC).内部RC振荡器(IRC_OSC).实时时钟振荡器(RTC_OSC).LPC17XX时钟框图如 ...
- 关闭一个winform窗体刷新另外一个
例如Form1是你的主窗体,然后Form2是你的要关闭那个窗体,在Form1中SHOW FORM2的窗体那里加上一句f2.FormClosed += new FormClosedEventHandle ...
- php练习1——计算器
目标:输入两个数,计算两个数的和/差/积/商 程序如下:两个文件jiSuanQi.html和jiSuanQi.php 结果如下:
- call_user_func_array
call_user_func_array — 调用回调函数,并把一个数组参数作为回调函数的参数 参数 callback 被调用的回调函数. param_arr 要被传入回调函数的数组,这个数组得是索引 ...