倍增法求最近公共祖先 lca
来源:互联网 发布:cmd查找他机mac 编辑:程序博客网 时间:2024/05/16 04:57
lca:
在树上的两节点都向上走最先找到的公共祖先。
倍增:
fa[x][i]表示x节点的第2^i个祖先(fa[x][0]就表示父节点),deep[x]表示节点的深度。
大致思路:
1.dfs建树,同时确定每个节点的父节点,更新deep数组,x节点的deep值为其父节点的deep值+1。
2.由fa数组定义可得,fa[x][j]=fa[fa[x][j-1]][j-1],即第2^(j-1)个祖先的第2^(j-1)个祖先,因为2^(j-1)+2^(j-1)=2^j。所以我们用此性质准备好fa数组以及deep数组(prepare函数)。
3.lca函数,对于查询的两个点x,y。如果x==y直接返回x。继续,令x为deep值大的点。说不清具体看代码解释。
代码:
#include<stdio.h>#include<string.h>#include<algorithm>#include<iostream>using namespace std;int scan(){ int x=0; char c=getchar(); while(c>'9'||c<'0') c=getchar(); while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+c-'0', c=getchar(); return x;}struct node{ int to,next,dis;};node edge[101000];int edge_num,pre[101000];int fa[101000][20],Log,deep[101000];int n,m;void add(int x,int y){ edge[++edge_num].next=pre[x]; edge[edge_num].to=y; pre[x]=edge_num; return;}void dfs(int x){ int i; for(i=pre[x];i;i=edge[i].next){ int v=edge[i].to; if(v==fa[x][0])continue; //注意 deep[v]=deep[x]+1; //准备deep数组 fa[v][0]=x; dfs(v); } return;}void prepare(){ for(int j=1;j<=Log;j++) //准备fa数组 for(int i=1;i<=n;i++) fa[i][j]=fa[fa[i][j-1]][j-1]; return;}int lca(int x,int y){ if(x==y)return x; //如果x==y,返回x if(deep[x]<deep[y]) //令x为deep大的点 swap(x,y); for(int i=Log;i>=0;i--) //令x与y的深度相同 if(deep[fa[x][i]]>=deep[y]&&fa[x][i]) //防止y为根 x=fa[x][i]; //往上跳//倍增优势在于跳得快,且不会跳过 if(x==y) //如果x==y,返回x return x; for(int i=Log;i>=0;i--){ //令x与y同时向上跳(相同步数) if(fa[x][i]!=fa[y][i]){ x=fa[x][i];y=fa[y][i]; } } return fa[x][0]; //注意,返回x的父节点}int main(){ n=scan();m=scan(); int i; for(Log=0;(1<<Log)<=n;Log++); //Log为树的最大深度 Log--; for(i=1;i<=n-1;i++){ int x=scan(),y=scan(); add(x,y); add(y,x); } dfs(1); prepare(); for(i=1;i<=m;i++){ //m个询问 int x=scan(),y=scan(); printf("%d\n",lca(x,y)); }}
阅读全文
1 0
- 倍增法求最近公共祖先 lca
- LCA 在线倍增法 求最近公共祖先
- 倍增法求最近公共祖先(LCA)
- 最近公共祖先(LCA)---倍增法
- 树上倍增求LCA(最近公共祖先)
- LCA最近公共祖先(朴素+倍增法)
- LCA(最近公共祖先)倍增法模板及总结
- LCA(最近公共祖先)倍增法实现
- 最近公共祖先(LCA)之树上倍增法
- 最近公共祖先 LCA 倍增算法
- 最近公共祖先(LCA):倍增
- 最近公共祖先 LCA 倍增+Tarjan实现
- poj 1986 最近公共祖先 (lca 倍增)
- 最近公共祖先LCA倍增算法
- LCA(最近公共祖先)倍增算法
- 最近公共祖先 LCA 倍增算法
- 【LCA倍增模板】【poj1330】最近公共祖先
- 【LCA】求最近公共祖先
- 使用ffmpeg获取关键帧图片
- 线性代数的本质(Essense Of Linear Algebra)[4]
- 513. Find Bottom Left Tree Value
- pat 乙级 1040. 有几个PAT(25)
- navicat for mysql 10.0.11 简体免安装中文破解版
- 倍增法求最近公共祖先 lca
- two-sum
- Matlab 定义函数的几种方法
- 练习2
- 9.6 今天学到了什么
- Android学习资源
- 一脸懵逼学习oracle(图形化界面操作---》PLSQL图形化界面)
- 【深入理解JVM】:类加载器与双亲委派模型
- NOIP2014 lgP2312 解方程(秦九韶算法+hash)