最近公共祖先
最近公共祖先的问题已经在前面的博客有说过了。
要看代码的,本篇博客写的是普通树的最近公共祖先,并不是二叉树,也许有时间我会写一下
在线算法
思想
对树进行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