ST算法与LCA
来源:互联网 发布:postek标签打印机软件 编辑:程序博客网 时间:2024/04/29 06:42
上一次我们讲到了倍增算法。倍增算法是O(nlogn)-O(logn)的复杂度,这里我们介绍另外一种方法,可以达到O(nlogn)-O(1)的复杂度。事实上,在经过+-1RMQ的处理,可以做到O(n)-O(1)的复杂度。
先举个例子:
我们设L[i]为第i次访问到的节点编号,d[i]为第i次访问到的节点的深度,fir[i]为节点编号为i在L中第一次出现的位置。则:
L: 1,2,5,2,6,2,1,3,1,4,7,8,7,4,1
D:1,2,3,2,3,2,1,2,1,2,3,4,3,2,1
fir:1,2,8,10,3,5,11,12
由于每条边都出现了两次,则可以得出,L的长度是2n-1。
如果现在要求6,7的LCA,则:
L: 1,2,5,2,6,2,1,3,1,4,7,8,7,4,1
D:1,2,3,2,3,2,1,2,1,2,3,4,3,2,1
可以发现,红色区域的最小值的位置所对应的L数组中的数即是LCA了。
则:LCA(T,x,y) = L[RMQ(D,fir[x],fir[y])]
这样做的时间复杂度就是O(nlogn)-O(1)。
只不过RMQ记录的不是最小值,而是最小值所在的位置。
如果还有些不懂的,请看程序:
#include <cstdio>#include <iostream>#include <algorithm>#include <cstring>#include <string>#include <vector>#include <queue>#include <stack>#include <map>#include <set>#include <cmath>using namespace std;#define Maxn 100010vector<int> adj[Maxn];int l[Maxn<<1],d[Maxn<<1];int fir[Maxn];int f[Maxn<<1][22];int tot;int n,q;void AddEdge(int x,int y){adj[x].push_back(y);adj[y].push_back(x);}void dfs(int u,int pre,int depth){++tot;l[tot] = u; d[tot] = depth; fir[u] = tot;int len = adj[u].size();for(int i=0;i<len;i++){int v = adj[u][i];if(v != pre){dfs(v,u,depth+1);++tot;l[tot] = u; d[tot] = depth;}}}void Init_RMQ(){for(int i=1;i<=tot;i++) f[i][0] = i;for(int j=1;(1<<j)<=tot;j++)for(int i=1;i+(1<<j)-1 <= tot;i++){int A = f[i][j-1],B = f[i+(1<<(j-1))][j-1];f[i][j] = d[A] < d[B]?A:B;}}int Ask_RMQ(int x,int y){if(x > y) swap(x,y);int k = log(y-x+1.0) / log(2.0);int A = f[x][k],B = f[y-(1<<k)+1][k];return d[A] < d[B]?A:B;}int LCA(int x,int y){x = fir[x]; y = fir[y];if(x>y) swap(x,y);return l[Ask_RMQ(x,y)];}int main(){scanf("%d",&n);int x,y;for(int i=1;i<n;i++){scanf("%d%d",&x,&y);AddEdge(x,y);}dfs(1,0,1);Init_RMQ();scanf("%d",&q);while(q--){scanf("%d%d",&x,&y);printf("%d\n",LCA(x,y));}return 0;}
阅读全文
0 0
- ST算法与LCA
- LCA(st算法)
- LCA-ST算法&Tarjan_LCA
- LCA st算法
- LCA在线算法ST算法
- LCA在线算法ST算法
- LCA算法-ST在线算法
- LCA之ST算法模板
- LCA(dfs+st)在线算法
- [CF 191C]Fools and Roads[LCA Tarjan算法][LCA 与 RMQ问题的转化][LCA ST算法]
- RMQ算法以及LCA的ST算法。
- HDU 3078 - Network(LCA'ST算法)
- hdu 2586 lca-st在线算法
- RMQ转换LCA模板 ST算法
- LCA在线算法ST&&DFS->POJ1330&&POJ1470
- 浅谈LCA的在线算法ST表
- LCA之倍增及ST算法
- LCA之ST算法模板 poj-1986
- iOS 使用OpenSSL库
- Linux内核编译学习
- JAVA的垃圾回收机制
- JVM调优总结 -Xms -Xmx -Xmn -Xss
- SEED-DVS6467_SDK安装问题
- ST算法与LCA
- jquery对select下拉框的一些基本操作
- busybox linux-2.6.2 Que1:arm-linux-gcc: command not found Que2:Makefile:mixed implicit and normal rules Q3:libstdc++.so.6 libst
- 公约数和公倍数
- gdb调试命令
- Linux下的Mysql数据库备份+还原
- kernel hacker修炼之道
- Windows驱动开发技术详解
- kubernetes资源对象--pod和job