【最近公共祖先】树倍增算法
来源:互联网 发布:mac用户头像 编辑:程序博客网 时间:2024/05/17 09:47
想想当年单纯的以为树剖求最近公共祖先就行啦,学什么LCA,结果NOIP2016原地爆炸……
所以说来填个坑
用类似st表的方法,来记录祖先。
从上至下,找公共祖先,最后一个肯定是最近的了。
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>using namespace std;struct node{ int x,y,next;}a[210000];int len,last[110000];void ins(int x,int y){ a[++len].x=x;a[len].y=y; a[len].next=last[x];last[x]=len;}//f[i][j]表示j的第2^i的祖先int Bin[30],dep[110000],f[25][110000];void dfs(int x,int fa){ f[0][x]=fa; for(int i=1;Bin[i]<=dep[x];i++)f[i][x]=f[i-1][f[i-1][x]]; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(y!=fa) { dep[y]=dep[x]+1; dfs(y,x); } }}int LCA(int x,int y){ if(dep[x]<dep[y])swap(x,y); for(int i=20;i>=0;i--) if(dep[x]-dep[y]>=Bin[i])x=f[i][x]; if(x==y)return x; for(int i=20;i>=0;i--) if(dep[x]>=Bin[i]&&f[i][x]!=f[i][y]){x=f[i][x];y=f[i][y];} return f[0][x];}int main(){ Bin[0]=1;for(int i=1;i<=25;i++)Bin[i]=Bin[i-1]*2; int n,m,x,y; scanf("%d%d",&n,&m); len=0;memset(last,0,sizeof(last)); for(int i=1;i<n;i++) { scanf("%d%d",&x,&y); ins(x,y);ins(y,x); } dep[1]=1;dfs(1,0); while(m--) { scanf("%d%d",&x,&y); printf("%d\n",LCA(x,y)); } return 0;}
阅读全文
0 0
- 【最近公共祖先】树倍增算法
- 最近公共祖先 LCA 倍增算法
- 最近公共祖先LCA倍增算法
- LCA(最近公共祖先)倍增算法
- 最近公共祖先 LCA 倍增算法
- 最近公共祖先(LCA)及其倍增算法实现
- c++最近公共祖先LCA(倍增算法和tarjan)
- 倍增LCA(最近公共祖先)算法详解
- [笔记]LCA最近公共祖先---倍增在线算法
- 树上两点最近公共祖先LCA的倍增算法 poj1986
- 最近公共祖先离线加在线倍增
- 最近公共祖先(LCA)---倍增法
- 最近公共祖先(LCA):倍增
- 最近公共祖先 LCA 倍增+Tarjan实现
- poj 1986 最近公共祖先 (lca 倍增)
- 倍增法求最近公共祖先 lca
- 【LCA倍增模板】【poj1330】最近公共祖先
- 算法基础 - 树的最近公共祖先
- 团队!ACM不是一个人在战斗
- Java中ThreadLocal类的作用以及实现原理
- 开始日期到结束日期的天数和每天是星期几
- JAVA开发中DEBUG的使用
- CTO训练营第二站-2017深圳专场助你成为全方位的 CTO!
- 【最近公共祖先】树倍增算法
- CentOS7使用firewalld打开关闭防火墙与端口
- Service Hot ITSOM企业级应用SaaS平台—知识库
- 学习一项新技术,应该问自己四个问题
- 初识nodejs27
- java并发-问题-为啥我们覆写了run方法,却要调用start方法?
- listview网络请求数据并实现多条目展示
- 统计学习方法概述
- Struts2 action的三种实现方式