算法基础 - 最近公共祖先(在线算法/离线算法)

最近公共祖先

最近公共祖先的问题已经在前面的博客有说过了。

要看代码的,本篇博客写的是普通树的最近公共祖先,并不是二叉树,也许有时间我会写一下

在线算法

思想

对树进行dfs(也就是先序遍历),在遍历过程中,记录下遍历的顺序,这里要注意的是,遍历要记录下所有路径,包括节点的第二次访问,或第三次访问。然后这样就是一个数组了。

      0
     / \
    1   2
   /|\   \
  3 4 5   6
    /\
   7  8

例如上面这棵树,dfs的顺序是:

0  1  3  1  4  7  4  8  4  1  5  1  0  2  6  2  0

在dfs遍历的过程中,记录下每个节点在树中的深度以及每个节点在遍历序列第一次出现的位置。
例如以上节点深度数组如下:

depth : 0 1 1 2 2 2 2 3 3 //不一定是递增的,只不过这里是

而每个节点第一次出现在遍历序列的位置数组如下:

pos : 0 1 13 2 4 10 14 5 7

假如我们要找节点5 和 7 的祖先就下看这两个节点第一次出现的位置pos[5] = 10; pos[7] = 5; 这样在5 - 10之间的遍历序列为:7 4 8 4 1 5从这里面找到深度最小的节点,在一个数组区间找最小值使用的是RMQ-ST算法( 我上两篇博客: RMQ-ST算法传送门 )。找到了之后,就可以进行输出了!

代码实现

这里是用Hihocoder 1069 题目做例子写的代码。

//
//  main.cpp
//  HiHocoder
//
//  Created by Alps on 16/5/9.
//  Copyright © 2016年 chen. All rights reserved.
//
#include<iostream>
#include<cstring>
#include<string>
#include<vector>
#include<unordered_map>
#include<algorithm>

using namespace std;
vector<int> tree[100005];
unordered_map<string, int> map;
unordered_map<int, int> nameSet;
static 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值