LCA在线算法(RMQ st算法的结合)
2016-09-12 14:35
134 查看
转自点击打开链接
从中可以发现u,v的LCA一定在她们的最短路径上,也就是first[u]~first[v]之间,那么只要找到这之间的最小值,那么就找到了LCA的。
这基本就是这个lca的思想。
按照我的理解首先要dfs一边求出first [u],deep[u],并且记录下first[u]所对应的u;
代码如下:
然后继续RMQ预处理,ST算法,这个是在上面所说的博客模板
所谓ST算法就是
令dp[i][j]为从下标i开始,长度为(1<<j)长的元素的最小值,那么状态转移方程就是
dp[i][j]=min{dp[i][j-1],dp[i+(2<<(j-1)][j-1]}
RMQ,原理是令k为满足(1<<k)<=(r-l+1)的最大整数,则以 l 开头的,长度为2的k次方的区间长度覆盖了查询区间(l,r),由于是求最小值,所以没有关系,但是如果是累加的话,就要错,那么他的结果就是min(dp[l][k],dp[r+1-(1<<k)][k]);
注意本来应该用dp数组来存最小值,pos数组来存位置,现在我去掉了pos数组,用dp数组存位置,那么最小时其实只要用位置访问dep数组就可以了。
从中可以发现u,v的LCA一定在她们的最短路径上,也就是first[u]~first[v]之间,那么只要找到这之间的最小值,那么就找到了LCA的。
这基本就是这个lca的思想。
按照我的理解首先要dfs一边求出first [u],deep[u],并且记录下first[u]所对应的u;
代码如下:
void dfs(int fa,int d) { vis[fa]=1; ver[++tot]=fa; first[fa]=tot; dep[tot]=d; for(int i=head[fa];i!=-1;i=edge[i].next){ int v=edge[i].v; if(!vis[v]) { dfs(v,d+1); ver[++tot]=fa; dep[tot]=d; } } }
然后继续RMQ预处理,ST算法,这个是在上面所说的博客模板
所谓ST算法就是
令dp[i][j]为从下标i开始,长度为(1<<j)长的元素的最小值,那么状态转移方程就是
dp[i][j]=min{dp[i][j-1],dp[i+(2<<(j-1)][j-1]}
void ST(int N) { for(int i=1;i<=N;i++) dp[i][0]=i; for(int j=1;(1<<j)<=N;j++) { for(int i=1;i<=N;i++) { if(i+(1<<(j-1))<=N) { int a=dp[i][j-1],b=dp[i+(1<<(j-1))][j-1]; dp[i][j]=dep[a]<dep[b]?a:b; } } } }
RMQ,原理是令k为满足(1<<k)<=(r-l+1)的最大整数,则以 l 开头的,长度为2的k次方的区间长度覆盖了查询区间(l,r),由于是求最小值,所以没有关系,但是如果是累加的话,就要错,那么他的结果就是min(dp[l][k],dp[r+1-(1<<k)][k]);
int RMQ(int x,int y) { int k=floor(log(y-x+1)/log(2)); int a=dp[x][k],b=dp[y-(1<<k)+1][k]; return dep[a]<dep[b]?a:b; } int LCA(int u,int v) { int x=first[u],y=first[v]; if(x>y) swap(x,y); int pos=RMQ(x,y); return ver[pos]; }
注意本来应该用dp数组来存最小值,pos数组来存位置,现在我去掉了pos数组,用dp数组存位置,那么最小时其实只要用位置访问dep数组就可以了。
相关文章推荐
- jqGrid与Struts2的结合应用(六) ------ 使用colModel设置查询功能 .
- 实例:SSH结合Easyui实现Datagrid的批量删除功能
- 玩转spring boot——结合AngularJs和JDBC
- WebWork结合Ajax提供国家,省市级联菜单
- 使用类前置声明的好处-结合Qt 4一个主窗口实例讲解
- Windows系统结合MinGW搭建软件开发环境
- asp.net 利用微软数据访问类库结合AjaxPro实现无刷新下拉框级联
- JQuery DataTable 结合SpringMVC+Spring Data JPA应用(二)
- 阅读博客后结合自身经历的心得体会
- (转)OpenCv与Qt的结合,几种方法的比较
- UVALive - 4726 Average 数型结合
- 结合require.js jquery 制作弹框组件
- Android中ListView结合CheckBox判断选中项
- Android照片墙完整版,完美结合LruCache和DiskLruCache
- 动态代理-annotation结合
- [翻译]轻松7步,导出Y结合子
- ajax 结合struts实现跨域访问
- 自动消失的小提示-结合xib
- 获取当前时间,并把两个字符串结合在一起
- 结合Vim ghostscript 将源代码文件转换成语法高亮的pdf格式文档