Lca树链剖分法
来源:互联网 发布:stl源码是什么 编辑:程序博客网 时间:2024/05/18 02:51
树链剖分各数组的作用:
son[]:最重的儿子节点,即节点最多的那个
bulk[]:所有儿子节点的总和(包括儿子的儿子)
dep[]:该节点的深度
ft[]:该节点的父亲
top[]:链的最上方的节点
首先Dfs预处理出前面的四个数组。
然后第二个Dfs进行剖分,预处理出最后一个数组。
例子:
此时son[1]=3(因为bulk[3]=6>bulk[2]=5),son[3]=10,son[4]=5,以此类推。
然后剖分之后相当于变成了
此时top[10]=1,top[7]=7,top[8]=9,以此类推
接下来就是进行Lca,假设c=lca(a,b),首先,当a,b在同一条重链中时,c=min(dep[a],dep[b]),当a,b不在同一条重链中时,画图易知c一定是划分轻重链的的那个分支点,比如图中的1,3,4。假设我们现在要求lca(7,8),那么lca(7,8)一定是某条直到7,8在同一条重链时的分支点,所以不断地把7,8向上合并到重链中,直到他们在同一条重链中。
现在进行模拟,先看看代码中的Lca,方便理解。令x=7,y=8,因为dep[top[x]]>dep[top[y]](top[x]=7,top[y]=9),所以更新x=4,发现top[x](top[x]=2),top[y](top[y]=9)不在一条重链中,继续更新,此时dep[top[y]]大,更新y=3,因为dep[top[x]]大,更新x=1,发现他们已经在同一条重链中,那么深度小的即为lca(7,8)
附模板:
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int MAXN = 1000;struct Edge{ int v, next; Edge(int v=0,int next=0):v(v),next(next){}}edge[MAXN];int head[MAXN], edgenum;//邻接表int son[MAXN], bulk[MAXN], dep[MAXN], ft[MAXN], top[MAXN];void toInit(){ memset(head, -1, sizeof(head)); edgenum = 0;}void toAdd(int u,int v){ edge[edgenum] = Edge(v, head[u]); head[u] = edgenum++;}void toDfs1(int u,int f,int tier){ son[u] = 0;dep[u] = tier;ft[u] = f;bulk[u] = 1; for (int i = head[u];i != -1;i = edge[i].next) { int v = edge[i].v; if (v == f) continue; toDfs1(v, u, tier + 1); bulk[u] += bulk[v]; if (bulk[v] > bulk[son[u]])//son[]更新为重儿子 son[u] = v; }}void toDfs2(int u,int f,int rt){ top[u] = rt; for (int i = head[u];i != -1;i = edge[i].next) { int v = edge[i].v; if (v == f) continue; if (v == son[u])//链剖分 toDfs2(v, u, rt);//重链top继承父亲的top else toDfs2(v, u, v);//轻链top为自身 }}int toLca(int x,int y){ while (top[x] != top[y]) { if (dep[top[x]] < dep[top[y]]) swap(x, y);//使深度大的始终为x x = ft[top[x]]; } return dep[x] < dep[y] ? x : y;}int main(){ return 0;}
阅读全文
0 0
- Lca树链剖分法
- LCA
- LCA
- lca
- LCA
- LCA
- lca
- LCA
- LCA
- LCA
- LCA
- LCA
- lca
- lca
- LCA
- lca
- LCA
- LCA
- 懒加载
- Removing Columns
- Java-----隐藏手机号中间四位
- NYOJ【22】素数求和问题【水题】
- spring中@value注解需要注意
- Lca树链剖分法
- 1px
- JDBC相关(三):DButils工具类的使用详解
- linux_centos下安装redis
- 在linux服务器中的项目绑定域名
- 机器学习中的范数规则化之(一)L0、L1与L2范数
- 从零开发一个完整的Android项目(二)——HTTP通信
- 递归加一些思考(钥匙计数之二)
- 使用Spring MVC统一异常处理实战