最近公共祖先LCA--Tarjan算法
来源:互联网 发布:最优化方法袁亚湘孙文 编辑:程序博客网 时间:2024/06/07 11:45
最近公共祖先 Lowest Common Ancestors
在一棵树中,两个结点之间第一个共同的祖先。
如图:
结点10和11的公共祖先有1、7、8、⑨四个节点,但是只有⑨是离其最近的,所以只有⑨是LCA
同理,3和11的LCA即是根节点1。2和4的LCA是2。
Tarjan算法:
其实讲个道理,我也不知道究竟是不是tarjan算法,因为网上说这个dfs序离线做法不是tarjan啥的,姑且这么叫吧。。反正复杂度也是很低
dfs序:
作为OI利器大法师–dfs–深度优先搜索
据说是只要你dfs学得好,你就能一等,你就能拿金
所谓dfs序,就是按照dfs遍历的顺序记录下点的顺序。
再比如,还是上图为例:
若是我们遍历的顺序是从左到右,则dfs序是这样的:
- 1-2-3-2-4-5-4-6-4-2-1-7-8-9-10-9-11-9-8-7-1
有这个实例在,应该可以理解了吧。
继续:
既然提到了dfs序的概念,我想很多人已经知道接下来怎么求LCA了
没错,就是在两个结点中找到深度最小的那个结点。
没错就是这么的。。简单
没有想象中的复杂吧。。这就是算法的迷人之处呢。
代码:
#include<cstdio>#include<iostream>#include<algorithm>#define maxn 100005using namespace std;struct node{ int next; int to; int w;}edge[maxn];int c=0,lc,ans,e=0,q,n,m;int find_p[maxn],dfs_d[maxn],dfs_p[maxn],dfs_w[maxn],head[maxn];void add(int u,int v,int d){ edge[++e].next=head[u]; edge[e].to=v; edge[e].w=d; head[u]=e; return ;}void dfs_lca(int pre,int now,int deep,int weight){//遍历从第一个点开始,第一个输入的点-->根 c++;//遍历顺序编号 dfs_p[c]=now;//此节点的下标 dfs_d[c]=deep;//深度 dfs_w[c]=weight;//权值和-->沿路权值和 for(int i=head[now];i!=0;i=edge[i].next){//now相连的所有点 if(edge[i].to!=pre){//不向上 dfs_lca(now,edge[i].to,deep+1,weight+edge[i].w);//继续dfs c++;//回到这个节点 dfs_p[c]=now;//同样记录 dfs_d[c]=deep; dfs_w[c]=weight; } } c++;//同样又一次回到了起点 dfs_p[c]=now; dfs_d[c]=deep; dfs_w[c]=weight; find_p[now]=c;//now这个点最后被记录的位置 return ;}void lca(){ dfs_lca(0,1,1,0); return ;}void find_lca(int u,int v){ if(find_p[u]>find_p[v]) swap(u,v); int ans=min(dfs_d[find_p[u]],dfs_d[find_p[v]]); for(int i=find_p[u];i<=find_p[v];i++){ if(dfs_d[i]<ans) lc=dfs_p[i]; } return ;}int main(){ int u,v,d; scanf("%d",&m); for(int i=1;i<=m;i++){ scanf("%d%d%d",&u,&v,&d); add(u,v,d); add(v,u,d); } lca(); scanf("%d",&q); for(int i=1;i<=q;i++){ scanf("%d%d",&u,&v); find_lca(u,v); printf("%d",lc); } return 0;}
代码中使用的数据结构是链表,但是是用数组模拟的办法,需要学习这种方法的同学可以去我的另一篇博客:
http://blog.csdn.net/Shiina_Orez/article/details/78724156 –>数组模拟链表
祝各位OIer武运昌隆!!!
阅读全文
0 0
- LCA最近公共祖先(tarjan离线算法)
- 最近公共祖先LCA:Tarjan算法
- 最近公共祖先LCA Tarjan算法
- 最近公共祖先LCA Tarjan算法
- 最近公共祖先LCA Tarjan算法
- 最近公共祖先LCA:Tarjan算法
- LCA(最近公共祖先)Tarjan算法
- [算法] LCA 最近公共祖先 (Tarjan)
- 最近公共祖先LCA--Tarjan算法
- 最近公共祖先LCA tarjan
- 【算法】【树】最近公共祖先LCA——Tarjan算法
- 算法摘记 最近公共祖先LCA Tarjan算法
- LCA最近公共祖先——tarjan算法
- Tarjan算法求LCA(最近公共祖先)
- Tarjan离线算法求最近公共祖先(LCA)
- POJ1986 DistanceQueries 最近公共祖先LCA 离线算法Tarjan
- Tarjan离线算法求最近公共祖先(LCA)
- LCA(最近公共祖先)tarjan算法学习笔记
- ccache 优化C++编译速度
- 配置jdk,maven环境变量
- ActvieMQ简单使用
- 常见的错误码
- C语言 可变参数
- 最近公共祖先LCA--Tarjan算法
- INSERT 语句与 FOREIGN KEY 约束"XXX"冲突。该冲突发生于数据库"XXX",表"XXX", column 'XXX。
- leetcode 395. Longest Substring with At Least K Repeating Characters 最长K个数量的字符 + DFS深度优先搜索
- java泛型
- Leetcode解题笔记 64. Minimum Path Sum [Medium] 动态规划
- 神经网络浅讲:从神经元到深度学习
- Android show memory info cmd
- 深度学习发展简要笔记
- C++编程之SOUI库listview学习(加入单选按钮)