LCA的 Trajan 算法
参考博客
参考博客
根据博客的模拟,就可以知道做法和思想。
现在就是实现他。
例题 :hdu 2586
题意:m 个询问,x 到 y 的距离,我们的思想就是求出:x到根的距离+y到根的距离-2*(lca[ x ,y ])到跟的距离。
代码:
#include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> using namespace std; const int max_edge=100005;//边数 const int max_Q=405;//问题 const int max_=40005;//节点 struct Tree{//树-邻接表int to;int v;int next; }; struct Question{//离线-问题int to;int id;int next; }; struct Tree a[max_edge];//树数组 struct Question b[max_];//问题数组 int N,M; int edge[max_];//边记录next int tot1,tot2; bool vis[max_];//标记数组 int st[max_Q],ed[max_Q];//问题的x和y int question[max_];//问题-记录next int fa[max_];//父节点 int dis[max_];//到根的距离 int LCA[max_Q];//问题的LCA void add_edge(int x,int y,int v)//建树 {a[++tot1].to=y;a[tot1].v=v;a[tot1].next=edge[x];edge[x]=tot1; } void add_question(int x,int y,int id)//离线 {b[++tot2].to=y;b[tot2].id=id;b[tot2].next=question[x];question[x]=tot2; } int find_fa(int x)//寻找父节点 {if(fa[x]==x)return x;return fa[x]=find_fa(fa[x]); } void Tarjan(int x) {fa[x]=x;//作为当前的根节点,将其父亲指向自己vis[x]=1;//标记for(int i=question[x];i;i=b[i].next)//寻找问题中与自己有关节点 {int go_to=b[i].to;if(vis[go_to]==true)//如果有关节点走过,记录LCALCA[b[i].id]=find_fa(go_to);}for(int i=edge[x];i;i=a[i].next)//沿边遍历 {int go_to=a[i].to;if(vis[go_to]==false){dis[go_to]=dis[x]+a[i].v;//更新距离Tarjan(go_to);//递归遍历fa[go_to]=x;//归并父节点 }} } int main() {int T;cin>>T;//测试组数while(T--){memset(vis,0,sizeof(vis));memset(question,0,sizeof(question));memset(edge,0,sizeof(edge));memset(dis,0,sizeof(dis));memset(LCA,0,sizeof(LCA));tot1=0,tot2=0;//初始归零cin>>N>>M;for(int i=0;i<N-1;i++){int x,y,v;cin>>x>>y>>v;add_edge(x,y,v);//双向建边 add_edge(y,x,v);}for(int i=0;i<M;i++){int x,y;cin>>x>>y;add_question(x,y,i);add_question(y,x,i);//保证找有关点时不漏st[i]=x,ed[i]=y;//记录问题的x,y }Tarjan(1);for(int i=0;i<M;i++){int temp=dis[st[i]]+dis[ed[i]]-(2*dis[LCA[i]]);//结果cout<<temp<<endl;}} }
转载于:https://www.cnblogs.com/linhaitai/p/9736115.html
LCA的 Trajan 算法相关推荐
- HDU - 2586 How far away LCA+tanjar离线算法
传送门 题意:求树上的两点的距离,放在一棵树上,而且题目提示只有一条,很明显是这条路线一定会经过他们的最近公共祖先啦,然后就是一个求距离的问题了.如果要采用离线算法的话,就是通过处理所有询问,那么肯定 ...
- POJ 1470 Closest Common Ancestors (最近公共祖先LCA 的离线算法Tarjan)
Tarjan算法的详细介绍,请戳: http://www.cnblogs.com/chenxiwenruo/p/3529533.html #include <iostream> #incl ...
- 【HDU 4547 CD操作】LCA问题 Tarjan算法
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4547 题意:模拟DOS下的cd命令,给出n个节点的目录树以及m次查询,每个查询包含一个当前目录cur和 ...
- 关于树论【LCA树上倍增算法】
补了一发LCA,表示这东西表面上好像简单,但是细节真挺多. 我学的是树上倍增,倍增思想很有趣~~(爸爸的爸爸叫奶奶.偶不,爷爷)有一个跟st表非常类似的东西,f[i][j]表示j的第2^i的祖先,就是 ...
- 关节点和重连通分量,trajan算法实现(python)
问题:关节点和重连通分量 题目描述 假若在删去顶点v以及和v相关联的各边之后,将图的一个连通分量分割成两个或两个以上的连接分量,则称顶点v为该图的一个关节点.一个没有关节点的连通图称为重连通图.在重连 ...
- 小A的最短路(LCA、倍增算法学习)
链接:https://ac.nowcoder.com/acm/contest/549/F 来源:牛客网 小A的最短路 时间限制:C/C++ 3秒,其他语言6秒 空间限制:C/C++ 262144K,其 ...
- LCA 朴素算法+树差分倍增+Tarjan算法 三种算法实现c++代码实现
哔哩哔哩up视频:https://www.bilibili.com/video/BV1nE411L7rz?t=379 转载:http 文章目录 树差分 & 倍增LCA Tarjan 朴素算法 ...
- [BZOJ1602BZOJ1787BZOJ2144]树上LCA的算法巩固练习
简述求LCA的倍增算法 对于树上的所有节点,我们可以很轻松地通过dfs求出其直接的父亲节点以及其深度 通过类似RMQ的原理我们可以处理出每个节点的第2^i个父亲 //这个过程既可以在dfs之后双重循环 ...
- LCA算法以及原理详解
LCA-最近公共祖先 LCA(Least Common Ancestors),即最近公共祖先,这种描述是基于树结构的,也即我们通通常只在树结构中考虑祖先问题.树实际上就是图论中的有向无环图,而要研 ...
- 【转】BYV--有向图强连通分量的Tarjan算法
转自beyond the void 的博客: https://www.byvoid.com/zhs/blog/scc-tarjan 注:红色为标注部分 [有向图强连通分量] 在有向图G中,如果两个顶点 ...
最新文章
- python 多进程_说说Python多线程与多进程的区别?
- ADO.NET 快速入门(一):ADO.NET 概述
- c语言开发游戏趋势,都9012年了,为何我还坚持用C语言开发游戏
- 创建、修改、删除表总结
- Multi-thread--多线程运行实例
- 中科同向 备份软件 引领科技 存储未来
- 利用cad计算型材的弹性模量_已知阶梯形直杆受力如图所示,材料的弹性模量
- Astah Professional for Mac(UML建模工具)
- 手机端网页设计尺寸大小
- 一台游戏服务器支持多少人,网络游戏一个服务器可以容纳多少人同时在线?
- mysql error 1837_MySQL复制错误1837的相关缺陷一例——insert delay在GTID下异常binlog格式...
- cURL error 18: transfer closed with xxxxxxx bytes remaining to read
- 五个“时髦”技术被判死刑
- 置换群的整幂运算【置换群】
- Java 数据交换格式反射机制SpringIOC原理分析
- 木马核心技术剖析读书笔记之木马技术的发展趋势
- Android SDK环境变量配置及连接真机
- hexo更换next主题
- 电子技术基础(三)__电路分析基础__正弦交流电的相量表示法
- ocaml学习随笔-1