LCA 0.3
来源:互联网 发布:c语言图形函数库 编辑:程序博客网 时间:2024/05/17 04:44
LCA
0.3
目录
- LCA
- 基本概念
- Tarjan
- 大致思路
- 实现过程
- 倍增
- 基本思路
- 实现过程
基本概念
LCA是求最近公共祖先问题,有在线st/RMQ和离线Tarjan/并查集两种算法,以及倍增的特殊做法 (倍增是一种思想). 虽然倍增的做法更常见,但是两种都要遍历一次树,直接处理问题的Tarjan在时间上更好.选择更好的算法,而不是更多的常数优化应该是编程的好习惯 (仅供参考) .
Tarjan算法只需要遍历一次树 (一边遍历一边查询,所以要先存储询问) ,所以其时间复杂度是O(n+m (询问个数) ).
Tarjan
大致思路
- 从根节点出发开始搜索
- 找到所有子节点并继续搜索
- 在搜索过程中记录每个访问的点的lca
实现过程
int find(int i){ if(i!=f[i]) f[i]=find(f[i]); return f[i];}void lca(int u){ v[u]=true;//标记以访问过 for(int i=first[u];i;i=a[i].ne)//链式前向星在遍历时比较方便且省时间 { int e=a[i].t; if(v[e]) continue; //因为不清楚父子关系,为避免环,需要加一个标记 lca(e);//拓展e和它的子节点,同时遍历 f[e]=u;//将e并入u } for(int i=firs[u];i;i=b[i].ne) { int e=b[i].t; if(!v[e]) continue;//还没有访问到的点的父亲是它自己 if(i&1) //直接将答案与询问边一起存储,注意输出时要把i<<1 (双向存储询问) b[i+1].ans=b[i].ans=find(e); else b[i-1].ans=b[i].ans=find(e); }}
倍增
基本思路
倍增是一种快速的搜索方式,可以在较短的时间找到目标,但是因为是在线算法,在时间开销上可能比Tarjan大.简单来说,倍增就是跳跃式前进,以计算机习惯的运动方式 (二进制).预处理为O(nlogn),查询为常数级 (最多只需要到31) ,基本看成O(1).在询问数较大时可能会快一点 (但是因为不管是哪种算法都需要极大的空间开销,所以一般不需要作此类考虑)
实现过程
void dfs(int u){ d[u]=d[f[u][0]]+1;//子节点比父节点深度多1 for(int i=0;f[u][i];i++) f[u][i+1]=f[f[u][i]][i]; //可以结合关系并查集理解,简单的关系转换 for(int i=first[u];i;i=a[i].ne) if(!d[a[i].t])//如果没有处理过 { f[a[i].t][0]=u;//f[e]=u dfs(a[i].t);//继续拓展 }}int lca(int u,int v){ if(d[u]>d[v])//位运算交换 u^=v^=u^=v; for(int i=bb;i>=0;i--) if(d[f[v][i]]>=d[u]) v=f[v][i]; if(u==v) return v; for(int i=bb;i>=0;i--) if(f[v][i]!=f[u][i]) { v=f[v][i]; u=f[u][i]; } return f[u][0];//直接输出即可}int dete(unsigned x)//不用unsigned就RE,因为数字非常大 (十进制下)//bb=dete(n),用来判断位数,小优化.在卡常时效果会更好{ int n=1; if(x==0) return -1; if ((x>>16) == 0) {n = n+16; x = x<<16;} if ((x>>24) == 0) {n = n+8; x = x<<8;} if ((x>>28) == 0) {n = n+4; x = x<<4;} if ((x>>30) == 0) {n = n+2; x = x<<2;} n = n-(x>>31); return 31-n;}
阅读全文
0 0
- LCA 0.3
- LCA
- LCA
- lca
- LCA
- LCA
- lca
- LCA
- LCA
- LCA
- LCA
- LCA
- lca
- lca
- LCA
- lca
- LCA
- LCA
- Leetcode 3 Longest Substring Without Repeating Characters
- 网络扫描与监听---网络与系统安全实验
- MySQL的视图与索引
- FPGA驱动OLED动态显示(Verilog代码)——Demo演示(链接)
- 设计模式之桥梁模式
- LCA 0.3
- 参数估计与假设检验
- 碎片fragment
- 自考总结
- Java8的lambda表达式和函数式接口
- Java4Android笔记之Java中的面向对象基础(三)
- Linux搭建主从复制
- 【BZOJ1096】【ZJOI2007】仓库建设(斜率优化,动态规划)
- nyoj 119 士兵杀敌(三)线段树