Day13(LCA入门)

LCA

LCA(Least Common Ancestors),即最近公共祖先,是指在有根树中,找出某两个结点u和v最近的公共祖先。在这里,一个节点也可以是它自己的祖先。

以下为一棵由双向边构成的无根树。双向边具有两个方向,不能确定父子关系。所以我们选择一个点作为根节点,将其“拉”成有根树。

在这里插入图片描述
如图所示

对于点4,有祖先点2,点1

对于点5,有祖先点2,点1

而他们的最近公共祖先就为2

同理,点4,点3的最近公共祖先为1 点4,点2的最近公共祖先为2

在这里插入图片描述
方式

1.存边

1 2
2 5
2 6
2 4
1 3

vector存邻接表

① 2 3

② 5 6 4

链式前向星

定义结构体表示边

定义head数组代表点的头节点

在这里插入图片描述
2.确立根节点

无向图:给你

有向图:可能不给你,自己确定入度为0的点

离线tarjan

给你一个由整点 1 ~ n (1 ≤ n ≤ 105) 构成的区间,每个点都有一个对应的颜色,不同的颜色用不同的编号 a (1 ≤ a ≤ 105)表示,接下来m (1 ≤ m ≤ 105)次询问,每次询问1~k (1 ≤ k ≤ 105)区间内有多少种不同的颜色。

实现:

①记录下所有问题的信息和编号。

②dfs,先找所有询问,答案为另外一个节点在并查集中的根。

③再遍历下面的点,递归结束时加入并查集。

在线倍增

在有序的区间内找特定的数(二分)

从第一个数到到指定位置pos之间的距离为d,把d用二进制表示

1 2 3 4 5 6 7 8 11 11

假设在一段非递减的序列里,找最后一个10,那么目标元素在第10位,第1位和它的距离为9

9 → 1001

从大到小枚举二进制的位数,如果询问的位置小于等于需要的值,就把当前位置移动到询问的位置。

比如我们先询问24(16),1 + 16 > 10 ,已经超过了序列的长度,不做处理,接下来23(8),1 + 8 = 9,a9能满足,把当前位置移动第9位。接下来我们枚举剩下的的位数,询问9 + 4 和 9 + 2 时,询问到的位置超过了序列的长度,所以我们这些都不处理。到20(1)时,a10能满足,位置移动到10。

最后判断所在位置的值是否为10。如果10的值不存在,那么就会找到小于并且最接近目标值的元素的位置。

实现:

dfs处理出每个节点的深度,构造倍增数组。paru,i代表点u在depu - 2i深度的祖先是谁。

找LCA时,让深度大的节点往上跳,跳到和另一个节点深度相同。

接下来先判断两个节点是否为同一个节点。如果是,则当前所在位置为LCA。否则,让两个节点一起往上跳。

找到第一个相同的点?倍增不太好实现这一步,所以我们找最后一个不相等的位置,最后输出这个位置的父亲节点。

二分?树并非线性结构,不太好根据连续下标直接找到对应的元素,但是可以通过构造倍增数组来联系不同节点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值