LCA 倍增||树链剖分
方法1:倍增
1498ms
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=5e5+;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int n,q,root,a,b;
struct edge{
int v,ne;
}e[N<<];
int cnt=,h[N];
inline void ins(int u,int v){
cnt++;
e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
cnt++;
e[cnt].v=u;e[cnt].ne=h[v];h[v]=cnt;
}
int fa[N][],deep[N],vis[N];
void dfs(int u){
vis[u]=;
for(int j=;(<<j)<=deep[u];j++)
fa[u][j]=fa[fa[u][j-]][j-];
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v;
if(vis[v]) continue;
deep[v]=deep[u]+;
fa[v][]=u;
dfs(v);
}
}
int lca(int x,int y){
if(deep[x]<deep[y]) swap(x,y);
int bin=deep[x]-deep[y];
for(int i=;i<=;i++)
if((<<i)&bin) x=fa[x][i];//,printf("x %d\n",i); for(int i=;i>=;i--)
if(fa[x][i]!=fa[y][i]){
x=fa[x][i];
y=fa[y][i];
}
if(x==y) return x;
else return fa[x][];
}
int main(int argc, const char * argv[]) {
n=read();q=read();root=read();
for(int i=;i<=n-;i++) a=read(),b=read(),ins(a,b);
dfs(root);
for(int i=;i<=q;i++){
a=read();b=read();
printf("%d\n",lca(a,b));
}
return ;
}
方法2:树链剖分
1314ms
让链首深度大的走到重链的父节点直到在一条重链上,返回深度小的节点
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=5e5+;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int n,q,root,a,b;
struct edge{
int v,ne;
}e[N<<];
int cnt=,h[N];
inline void ins(int u,int v){
cnt++;
e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
cnt++;
e[cnt].v=u;e[cnt].ne=h[v];h[v]=cnt;
}
int fa[N],deep[N],mx[N],size[N];
void dfs(int u){
size[u]++;
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v;
if(v==fa[u]) continue;
fa[v]=u;deep[v]=deep[u]+;
dfs(v);
size[u]+=size[v];
if(size[v]>size[mx[u]]) mx[u]=v;
}
}
int tid[N],top[N],tot;
void dfs(int u,int anc){
if(!u) return;
tid[u]=++tot;top[u]=anc;
dfs(mx[u],anc);
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v;
if(v!=fa[u]&&v!=mx[u]) dfs(v,v);
}
}
int lca(int x,int y){
while(top[x]!=top[y]){
if(deep[top[x]]<deep[top[y]]) swap(x,y);
x=fa[top[x]];
}
if(deep[x]>deep[y]) swap(x,y);
return x;
}
int main(int argc, const char * argv[]) {
n=read();q=read();root=read();
for(int i=;i<=n-;i++) a=read(),b=read(),ins(a,b);
dfs(root);
dfs(root,root);
for(int i=;i<=q;i++){
a=read();b=read();
printf("%d\n",lca(a,b));
}
return ;
}
LCA 倍增||树链剖分的更多相关文章
- 洛谷P4180 [Beijing2010组队]次小生成树Tree(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)
洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...
- 洛谷P4180 [BJWC2010]次小生成树(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)
洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...
- 【BZOJ3626】LCA(树链剖分,Link-Cut Tree)
[BZOJ3626]LCA(树链剖分,Link-Cut Tree) 题面 Description 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1. ...
- 培训补坑(day8:树上倍增+树链剖分)
补坑补坑.. 其实挺不理解孙爷为什么把这两个东西放在一起讲..当时我学这一块数据结构都学了一周左右吧(超虚的) 也许孙爷以为我们是省队集训班... 好吧,虽然如此,我还是会认真写博客(保证初学者不会出 ...
- uva 12655 Trucks [LCA](树链剖分+MST)
The Subtle Balloons Company (SBC) is the main balloon provider for programming contests; it hashuge ...
- CF 191C Fools and Roads lca 或者 树链剖分
They say that Berland has exactly two problems, fools and roads. Besides, Berland has n cities, popu ...
- 从lca到树链剖分 bestcoder round#45 1003
bestcoder round#45 1003 题,给定两个点,要我们求这两个点的树上路径所经过的点的权值是否出现过奇数次.如果是一般人,那么就是用lca求树上路径,然后判断是否出现过奇数次(用异或) ...
- P3379 【模板】最近公共祖先(LCA)(树链剖分)版
#include <bits/stdc++.h> #define read read() #define up(i,l,r) for(register int i = (l);i < ...
- 2018.09.16 bzoj3626: [LNOI2014]LCA(树链剖分)
传送门 树链剖分好题. 对于每个点维护一个值vi" role="presentation" style="position: relative;"&g ...
随机推荐
- datagridview 单元格格式转换注意
datagridview 单元格内容进行比较时要注意正确写法要用强制转换,否则出错Convert.ToString(grd_order.SelectedRows[0].Cells[1].Value)= ...
- struts2的action是多例,servlet是单例
struts2中action是多例的,即一个session产生一个action如果是单例的话,若出现两个用户都修改一个对象的属性值,则会因为用户修改时间不同,两个用户访问得到的 属性不一样,操作得出的 ...
- [连载]《C#通讯(串口和网络)框架的设计与实现》- 5.串口和网络统一IO设计
目 录 第五章 串口和网络统一IO设计... 2 5.1 统一IO接口... 2 5.1.1 串口IO.. 4 5.1.2 网络IO.. ...
- JSP利用Hibernate实现对数据库的CRUD ——开发环境Myeclipse与SQL Server 2008
一.首先先建立一个Web Project 二.然后在程序根目录建立文件夹“DataBase”和“Doc”,分别存放数据库文件和保存SQL语句,建完如下所示: 三.建立数据库“dbHibernate”, ...
- javascript俄罗斯方块游戏
在线试玩:http://keleyi.com/game/5/ 操作指南:键盘方向键←→控制左右移动,↑键变形,↓键快速下落. 别看这段js代码只有短短的100多行,效果却非常不错,用键盘的方向键操作, ...
- vue+ vue-router + webpack 踩坑之旅
说是踩坑之旅 其实是最近在思考一些问题 然后想实现方案的时候,就慢慢的查到这些方案 老司机可以忽略下面的内容了 1)起因 考虑到数据分离的问题 因为server是express搭的 自然少 ...
- Bootstrap之样式风格与下拉菜单
背景颜色 bg-primary 字体颜色 text-primary 文字居中 text-center 按钮 btn btn-primary btn-default默认 btn-link链接 按钮大小 ...
- JQ中的方法、事件及动画
css( ) 除了可以为元素添加样式外,还可用来查询元素,某样式值alert($('.cls1').css('width')); //100px(返回带单位的值)注意:原生CSS样式中有-的去掉并且将 ...
- IE7浏览器窗口大小改变事件执行多次bug(转)
var resizeTimer = null; $(window).resize(function() { if (resizeTimer) clearTimeout(resizeTimer); re ...
- [Javascript]利用当前时间生成yyyymmddhhmmss这样的字符串
function pad2(n) { return n < 10 ? '0' + n : n } function generateTimeReqestNumber() { var date = ...