代码:

//RMQ求LCA
struct node {
int v, w;
};
class LCA {
private:
vector<int>dep, pos, olx, dis;
vector<vector<int>>st;
public:
LCA(vector<vector<node>> &G, int r) {
int sz = G.size();
pos.resize(sz);
dis.resize(sz, );
dep.resize(sz, );
function<void(int, int)>dfs = [&](int u, int fa) {
pos[u] = olx.size();
olx.push_back(u);
dep[u] = dep[fa] + ;
for(auto &i : G[u]) {
if(i.v != fa) {
dis[i.v] = dis[u] + i.w;
dfs(i.v, u);
olx.push_back(u);
}
}
};
dfs(r, r);
int n = olx.size(), m = log2(n) + ;
st.resize(n);
for(int i = ; i < n; i++) {
st[i].resize(m);
st[i][] = olx[i];
}
for(int j = ; j < m; j++) {
for(int i = ; i + ( << j) <= n; i++) {
int x = st[i][j - ], y = st[i + ( << (j - ))][j - ];
st[i][j] = dep[x] < dep[y] ? x : y;
}
}
}
int que(int u, int v) {
int l = pos[u], r = pos[v];
if(l > r) swap(l, r);
int k = log2(r - l + );
int x = st[l][k], y = st[r - ( << k) + ][k];
return dep[x] < dep[y] ? x : y;
}
int dist(int u, int v) {
int lca = que(u, v);
return dis[u] + dis[v] - * dis[lca];
}
}; 倍增求LCA
struct node {
int v, w; };
class LCA {
private:
vector<int>dep;
vector<vector<int>>anc;
vector<int>dis;
public:
LCA(vector<vector<node>> &G, int r) {
int n = G.size(), m = log2(n) + ;
anc.resize(n);
for(auto &i : anc) i.resize(m);
dep.resize(n);
dis.resize(n);
function<void(int, int)>dfs = [&](int u, int fa) {
anc[u][] = fa;
dep[u] = dep[fa] + ;
for(auto &i : G[u]) {
if(i.v != fa) {
dis[i.v] = dis[u] + i.w;
dfs(i.v, u);
}
}
};
dfs(r, r);
for(int j = ; j < m; j++) {
for(int i = ; i < n; i++) {
anc[i][j] = anc[anc[i][j - ]][j - ];
}
}
}
int que(int u, int v) {
if(dep[u] < dep[v]) swap(u, v);
for(int i = log2(dep[u]); i >= ; i--) {
if(dep[u] - ( << i) >= dep[v]) u = anc[u][i];
}
if(u == v) return u;
for(int i = log2(dep[u]); i >= ; i--) {
if(anc[u][i] != anc[v][i]) {
u = anc[u][i];
v = anc[v][i];
}
}
return anc[u][];
}
int dist(int u, int v) {
int lca = que(u, v);
return dep[u] + dep[v] - dep[lca] * ;
}
int kth_anc(int u, int k) { //u节点在k层的祖先
if(dep[u] < k) return -;
int d = dep[u] - k;
for(int i = log2(d); i >= ; i--) {
if(d - ( << i) >= ) {
d -= ( << i);
u = anc[u][i];
}
}
return u;
}
}; tarjan求LCA
struct node {
int v, w;
};
vector<int> LCA(vector<vector<node>> &G, int r, vector<node> &q) {
int n = G.size(), m = q.size();
vector<vector<node>>que(n);
vector<int>bcj(n), ans(m), dis(n);
iota(bcj.begin(), bcj.end(), );
for(int i = ; i < m; i++) {
que[q[i].v].push_back({q[i].w, i});
que[q[i].w].push_back({q[i].v, i});
}
function<int(int)>gr = [&](int k) {
return k == bcj[k] ? k : bcj[k] = gr(bcj[k]);
};
function<void(int, int)>dfs = [&](int u, int fa) {
cout << u << endl;
for(auto &i : G[u]) {
if(i.v != fa) {
dis[i.v] = dis[u] + i.w;
dfs(i.v, u);
bcj[i.v] = u;
}
}
for(auto &i : que[u]) {
if(bcj[i.v] != i.v || i.v == u) {
ans[i.w] = gr(i.v);
}
}
};
dfs(r, r);
return ans;
}

LCA 总结的更多相关文章

  1. BZOJ 3083: 遥远的国度 [树链剖分 DFS序 LCA]

    3083: 遥远的国度 Time Limit: 10 Sec  Memory Limit: 1280 MBSubmit: 3127  Solved: 795[Submit][Status][Discu ...

  2. BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2050  Solved: 817[Submit][Status ...

  3. [bzoj3123][sdoi2013森林] (树上主席树+lca+并查集启发式合并+暴力重构森林)

    Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...

  4. [bzoj2588][count on a tree] (主席树+lca)

    Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始 ...

  5. [板子]倍增LCA

    倍增LCA板子,没有压行,可读性应该还可以.转载请随意. #include <cstdio> #include <cstring> #include <algorithm ...

  6. poj3417 LCA + 树形dp

    Network Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4478   Accepted: 1292 Descripti ...

  7. [bzoj3626][LNOI2014]LCA

    Description 给出一个$n$个节点的有根树(编号为$0$到$n-1$,根节点为$0$). 一个点的深度定义为这个节点到根的距离$+1$. 设$dep[i]$表示点$i$的深度,$lca(i, ...

  8. (RMQ版)LCA注意要点

    inline int lca(int x,int y){ if(x>y) swap(x,y); ]][x]]<h[rmq[log[y-x+]][y-near[y-x+]+]])? rmq[ ...

  9. bzoj3631: [JLOI2014]松鼠的新家(LCA+差分)

    题目大意:一棵树,以一定顺序走完n个点,求每个点经过多少遍 可以树链剖分,也可以直接在树上做差分序列的标记 后者打起来更舒适一点.. 具体实现: 先求x,y的lca,且dep[x]<dep[y] ...

  10. 在线倍增法求LCA专题

    1.cojs 186. [USACO Oct08] 牧场旅行 ★★   输入文件:pwalk.in   输出文件:pwalk.out   简单对比时间限制:1 s   内存限制:128 MB n个被自 ...

随机推荐

  1. .net 学习官网

    https://docs.microsoft.com

  2. Android -ui控件

    一:TextView控件 TextView --> View 1.创建TextView的两种方式: 1.1编写TextView类 TextView tv = new TextView(this) ...

  3. leetcode.字符串.344反转字符串-Java

    1. 具体题目 编写一个函数,其作用是将输入的字符串反转过来.输入字符串以字符数组 char[] 的形式给出.不要给另外的数组分配额外的空间,你必须原地修改输入数组.使用 O(1) 的额外空间解决这一 ...

  4. python的小介绍

    Python简介 龟叔 优美.清晰.简单 主要应用领域: 云计算 WEB开发 科学技术.人工智能 系统运维 爬虫 金融量化分析 图形GUI 游戏 Python发展史 1989年,Guido开始写Pyt ...

  5. java中位运算和移位运算详解

    一.位运算 (1)按 位 与 & 如果两个相应的二进制形式的对应的位数都为1,则结果为1,记为同1为1,否则为0.首先我们看一下对正数的运算        分别看一下正数和负数的具体运算步骤 ...

  6. 数据仓库ETL案例学习(二)

    来自案例学习 数据仓库经过ETL成功创建之后,就可以对数据仓库进行多维分析任务. 任务主要分为: 1.设置数据源,并添加分析时所需表到数据视图. 2.创建并设置维度. 3.设置时间维. 4.设置度量属 ...

  7. 【问题解决方案】GitHub仓库重构之将某个或某些文件夹移动到其他文件夹内

    仓库重构时遇到的问题,在GitHub页面里好像没有类似的操作按钮? 搜了一下好像要用到一些命令比如rm等,但是我对Linux类的命令不是很熟悉 于是想试试曲线救国,先把远程库的文件pull到本地,在本 ...

  8. Css中的!important

    转载自:https://www.cnblogs.com/cang12138/p/7326280.html !important为开发者提供了一个增加样式权重的方法,比直接在元素的 style 属性中设 ...

  9. 2.Web中使用iReport 整合----------创建html格式的

    转自:https://wenku.baidu.com/view/104156f9770bf78a65295462.html 1.

  10. Git--01 基础 - 远程仓库的使用

    目录 Git 基础 - 远程仓库的使用 远程仓库的使用 查看远程仓库 添加远程仓库 从远程仓库中抓取与拉取 推送到远程仓库 查看某个远程仓库 远程仓库的移除与重命名 Git 基础 - 远程仓库的使用 ...