关于树论【LCA树上倍增算法】
补了一发LCA,表示这东西表面上好像简单,但是细节真挺多。
我学的是树上倍增,倍增思想很有趣~~(爸爸的爸爸叫奶奶.偶不,爷爷)有一个跟st表非常类似的东西,f[i][j]表示j的第2^i的祖先,就是说f[0][x]是父亲,f[1][x]是爷爷,f[2][x]是高祖父(爷爷的爷爷),f[3][x]是远祖父(高祖父的高祖父)
搞个事:
按古制辈份分为:自己,父亲、祖父、曾祖、高祖、天祖、烈祖、太祖、远祖、鼻祖。
扯回来,这个就是倍增的思想,可以方便的实现O(logn)的LCA,现在让你在构图的时候搞好f数组,一点问题都没有了吧~
然后怎么求LCA?首先,我们先让深度比较深的点往上跳,然后两个一起跳,直到跳到父亲相同。那我们跳的时候,就像二进制一样,可以一次跳2^i次方
caioj1236:(赤裸裸的LCA)
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
struct node
{
int x,y,next;
}a[];int len,last[];
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[],dep[],f[][];
void dfs(int x,int fa)//构树
{
f[][x]=fa;//x的2^0=1就是自己父亲
for(int i=;Bin[i]<=dep[x];i++)f[i][x]=f[i-][f[i-][x]];//倍增,爸爸的爸爸是爷爷
for(int k=last[x];k;k=a[k].next)
{
int y=a[k].y;
if(y!=fa)
{
dep[y]=dep[x]+;
dfs(y,x);
}
}
}
int LCA(int x,int y)
{
if(dep[x]<dep[y])swap(x,y);//让比较深的先往上跳
for(int i=;i>=;i--)//倒着,想象成二进制,比如要找第5个祖先,就变成101,从左往右把所有为一的跳一下
if(dep[x]-dep[y]>=Bin[i])x=f[i][x];
if(x==y)return x;
for(int i=;i>=;i--)//深度一样了,x和y一起跳
if(dep[x]>=Bin[i]&&f[i][x]!=f[i][y]){x=f[i][x];y=f[i][y];}
return f[][x];
}
int main()
{
Bin[]=;for(int i=;i<=;i++)Bin[i]=Bin[i-]*;
int n,m,x,y;
scanf("%d%d",&n,&m);
len=;memset(last,,sizeof(last));
for(int i=;i<n;i++)
{
scanf("%d%d",&x,&y);
ins(x,y);ins(y,x);
}
dep[]=;dfs(,);
while(m--)
{
scanf("%d%d",&x,&y);
printf("%d\n",LCA(x,y));
}
return ;
}
关于树论【LCA树上倍增算法】的更多相关文章
- Codevs 2370 小机房的树 LCA 树上倍增
题目描述 Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天,他们想爬到一个节点上去搞基,但是作为两只虫子, ...
- LCA的倍增算法
LCA,即树上两点之间的公共祖先,求这样一个公共祖先有很多种方法: 暴力向上:O(n) 每次将深度大的点往上移动,直至二者相遇 树剖:O(logn) 在O(2n)预处理重链之后,每次就将深度大的沿重链 ...
- LCA树上倍增求法
1.LCA LCA就是最近公共祖先(Least common ancestor),x,y的LCA记为z=LCA(x,y),满足z是x,y的公共祖先中深度最大的那一个(即离他们最近的那一个)qwq 2. ...
- LCA——树上倍增
首先,什么是LCA? LCA:最近公共祖先 祖先:从当前点到根节点所经过的点,包括他自己,都是这个点的祖先 A和B的公共祖先:同时是A,B两点的祖先的点 A和B的最近公共祖先:深度最大的A和B的公共祖 ...
- HDU 4822 Tri-war(LCA树上倍增)(2013 Asia Regional Changchun)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4822 Problem Description Three countries, Red, Yellow ...
- LCA树上倍增
LCA就是最近公共祖先,比如 节点10和11的LCA就是8,9和3的LCA就是3. 我们这里讲一下用树上倍增来求LCA. 大家都可以写出暴力解法,两个节点依次一步一步往上爬,直到爬到了相同的一个节点. ...
- BZOJ3545&3551[ONTAK2010]Peaks——kruskal重构树+主席树+dfs序+树上倍增
题目描述 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询问从点v开始只 ...
- Lca 之倍增算法
引入: 比如说要找树上任意两个点的路上的最大值.如果是一般的做法 会 接近o(n)的搜,从一个点搜到另一个点,但是如果询问多了复杂度就很高了. 然后我们会预处理.预处理是o(n²)的,询问是o(1)的 ...
- Codeforces 191C (LCA+树上差分算法)
题面 传送门 题目大意: 给出一棵树,再给出k条树上的简单路径,求每条边被不同的路径覆盖了多少次 分析 解决这个问题的经典做法是树上差分算法 它的思想是把"区间"修改转化为左右端点 ...
随机推荐
- 创意、实现和合作:一次原创H5的尝试
3月的某一天需求同学说:我们想做一个爆款的回流H5. 好的事实上并没有这么夸张. 不过我们确实是第一次真正意义上做这样一个以互动展示为主要形式.以传播和拉回流为主要目的的H5. 虽然最后也没有成为真正 ...
- Python 和 Flask实现RESTful services
使用Flask建立web services超级简单. 当然,也有很多Flask extensions可以帮助建立RESTful services,但是这个例实在太简单了,不需要使用任何扩展. 这个we ...
- SPOJ DCEPC11I
题目大意: 就是给定一段区间令其中的数增加一个递增序列(也就是说第一个+1,第二个+2.....) 询问操作是区间的和 这里的查询很简单,但是对于添加递增序列入区间就比较搞脑子了 我们需要一个add[ ...
- ubuntu 18.04取消自动锁屏以及设置键盘快捷锁屏
1:操作设置取消自动锁屏: setting-->power--->never 2: 设置自动锁屏快捷键: 快捷键设置一般在setting-->devices--->keybo ...
- Codevs 3409 搬礼物
时间限制: 1 s 空间限制: 64000 KB 题目等级 : 青铜 Bronze 题目描述 Description 小浣熊松松特别喜欢交朋友,今年松松生日,就有N个朋友给他送礼物.可是要把这些礼 ...
- CF830B:Cards Sorting
对叠放着的n张牌,第i张牌写有数字Ai,进行操作:将牌堆顶的牌取出,若是当前牌堆最小值就扔掉,否则放到牌堆底,求牌堆空时操作次数. 怎么看怎么像约瑟夫..不过约瑟夫DP我不太熟,于是就yy了一下 “当 ...
- 收藏CSS经典技巧
一. CSS字体属性简写规则 一般用CSS设定字体属性是这样做的: font-weight: bold; font- style: italic; font-varient: small-caps; ...
- [Bzoj3668][Noi2014]起床困难综合症(位运算)
3668: [Noi2014]起床困难综合症 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 2612 Solved: 1500[Submit][St ...
- NOIP2017 酱油记
Day0: 怀着激动无比的小心情,坐上了学校的校车. 然后司机在某个小县城迷路了,迷路了两个多小时.... 来到酒店,去吃了几把鸡,没见到鸡屁股... 洗了个澡早早睡了.. Day1: 一早被闹铃叫醒 ...
- mybatis几种开发方式
mybatis是比较轻巧的半自动化的CRM框架,它有几种开发方式,现今张列于此: 一.注解方式:在接口方法上面写SQL语句,有点类似springdataJPA 的query sql 语句 范例 @se ...