LCA 倍增算法模板】的更多相关文章

. #include <cstring> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cmath> #include <vector> using namespace std; +; vector <int> son[N]; ],in[N],a,b; void dfs(int prev,int rt){ depth[rt]=dept…
LCA 算法是一个技巧性很强的算法. 十分感谢月老提供的模板. 这里我实现LCA是通过倍增,其实就是二进制优化. 任何一个数都可以有2的阶数实现 例如16可以由1 2 4 8组合得到 5可以由1 2 4 组合得到 便于读者理解 我放一道例题吧 Problem F: 挑战迷宫 Description 小翔和小明正在挑战一个神奇的迷宫.迷宫由n个房间组成,每个房间的编号为1~n,其中1号房间是他们俩初始位置, 所有房间一共由n-1条路连接,使得房间两两之间能够相互达到(构成一棵树),每条路的长度为W…
      树上倍增求LCA LCA指的是最近公共祖先(Least Common Ancestors),如下图所示: 4和5的LCA就是2 那怎么求呢?最粗暴的方法就是先dfs一次,处理出每个点的深度 然后把深度更深的那一个点(4)一个点地一个点地往上跳,直到到某个点(3)和另外那个点(5)的深度一样 然后两个点一起一个点地一个点地往上跳,直到到某个点(就是最近公共祖先)两个点"变"成了一个点 不过有没有发现一个点地一个点地跳很浪费时间? 如果一下子跳到目标点内存又可能不支持,相对来说…
/* *********************************************** Author :kuangbin Created Time :2013-9-5 9:45:17 File Name :F:\2013ACM练习\专题学习\LCA\POJ1330_3.cpp ************************************************ */ #include <stdio.h> #include <string.h> #inclu…
倍增求 LCA 是在线的,而且比 ST 好写多了,理解起来比 ST 和 Tarjan 都容易,于是就自行脑补吧,代码写得容易看懂 关键理解 f[i][j] 表示 i 号节点的第 2j 个父亲,也就是往上走 2j 个节点 求 LCA 的时候先倍增让两点深度一样,再倍增求 另外丢两个链接,这两个有详细讲解 ST 算法 http://www.cnblogs.com/hadilo/p/5837517.html Tarajan 算法 http://www.cnblogs.com/hadilo/p/5840…
先上我原来的错误的代码 type node=^link; link=record num:int64; next:node; end; var fa:..,..] of int64; dep:..] of int64; nd:..] of node; b:..] of boolean; dl:..] of int64; n,m,maxdep,ans,t1,t2:int64; i:longint; procedure maketree; var t1,t2,head,tail:int64; i,j…
算法笔记 模板: vector<int>g[N]; vector<int>edge[N]; ][N]; int deep[N]; int h[N]; void dfs(int o,int u,int w) { ,h[u]=h[o]+w; ;j<g[u].size();j++) { if(g[u][j]!=o) { anc[][g[u][j]]=u; ;i<;i++)anc[i][g[u][j]]=anc[i-][anc[i-][g[u][j]]]; dfs(u,g[u]…
链接:http://poj.org/problem?id=1330 题意:q次询问求两个点u,v的LCA 思路:LCA模板题,首先找一下树的根,然后dfs预处理求LCA(u,v) AC代码: #include<iostream> #include<algorithm> #include<cmath> #include<cstring> #include<set> #include<string> #include<vector&…
链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 题意:n个村庄构成一棵无根树,q次询问,求任意两个村庄之间的最短距离 思路:求出两个村庄的LCA,dis[ i ] 表示结点 i 到树根的距离,那么任意两点u,v的最短距离就是dis[ u ]  - dis [LCA] + dis [ v ] - dis[ LCA ].代码是用tarjan做的,算是模板,记录一下. AC代码: #include<iostream> #include<cst…
概述 对于有根树T的两个结点u.v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u.v的祖先且x的深度尽可能大. 如图,3和5的最近公共祖先是1,5和2的最近公共祖先是4 在本篇中我们先介绍一下倍增算法 我们需要一个数组de[i]来表示每一个节点i的深度,用另一数组parent[i][j]来表示每一节点j向上走2的i次方是哪个节点 我们首先在初始化中算出每个点的深度和它的上一个点是什么(用parent[0][i]表示) 在此后我们进行倍增的处理:parent[1][j]=parent…