代码:

//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. Linear Regression and Gradient Descent

    随着所学算法的增多,加之使用次数的增多,不时对之前所学的算法有新的理解.这篇博文是在2018年4月17日再次编辑,将之前的3篇博文合并为一篇. 1.Problem and Loss Function ...

  2. 用jquery获取select标签中选中的option值及文本

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...

  3. Java_1.Java符号体系

    Java符号包含五类:标识符.关键字.常量及字面量.运算符.分隔符 1.标识符 定义:用于标明程序中元素的名字,如类.方法和变量 命名规则: ·由字母.数字.下划线(_)和美元符号($)构成的字母序列 ...

  4. django的配置

    1.django的默认配置 import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...) # 获取 ...

  5. CodeChef A String Game(SG)

    A String Game   Problem code: ASTRGAME   Submit All Submissions   All submissions for this problem a ...

  6. python学习第十天列表的增加,修改,删除操作方法

    在一个有序的数据列表中,集各种数据类型,可以向列表增加元素,也可以修改列表里面的元素,可以删除列表的里面元素,append(),insert(),remove(),pop(),和全局DEL 删除等. ...

  7. 使用git、git-flow与gitlab工作

    使用git.git-flow与gitlab工作 1. 摘要 在工作中使用git代替svn也有一段时间了,对于git的一些特性喜爱的同时也一直遇到相同的问题:“这时候应该打什么命令?”.相对于svn或者 ...

  8. worldcloud库的使用

    worldcloud库的使用 worldcloud是一个优秀的第三方词云展示库,用来实现比较有逼格的数据可视化效果.更加直观与艺术的展示单词. worldcloud对象的创建 worldcloud.W ...

  9. 一、Api

    一. private static readonly IList<string> BaseParamKey = new List<string>() { "apiId ...

  10. 4——class和struct

    class的定义看上去很像struct定义的扩展, 事实上,类定义时的关键字class完全可以替换成struct,也就是说,结构体变量也可以有成员函数. class和struct的唯一区别在于:str ...