LCA 总结
代码:
//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 总结的更多相关文章
- BZOJ 3083: 遥远的国度 [树链剖分 DFS序 LCA]
3083: 遥远的国度 Time Limit: 10 Sec Memory Limit: 1280 MBSubmit: 3127 Solved: 795[Submit][Status][Discu ...
- BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]
3626: [LNOI2014]LCA Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2050 Solved: 817[Submit][Status ...
- [bzoj3123][sdoi2013森林] (树上主席树+lca+并查集启发式合并+暴力重构森林)
Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...
- [bzoj2588][count on a tree] (主席树+lca)
Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始 ...
- [板子]倍增LCA
倍增LCA板子,没有压行,可读性应该还可以.转载请随意. #include <cstdio> #include <cstring> #include <algorithm ...
- poj3417 LCA + 树形dp
Network Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4478 Accepted: 1292 Descripti ...
- [bzoj3626][LNOI2014]LCA
Description 给出一个$n$个节点的有根树(编号为$0$到$n-1$,根节点为$0$). 一个点的深度定义为这个节点到根的距离$+1$. 设$dep[i]$表示点$i$的深度,$lca(i, ...
- (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[ ...
- bzoj3631: [JLOI2014]松鼠的新家(LCA+差分)
题目大意:一棵树,以一定顺序走完n个点,求每个点经过多少遍 可以树链剖分,也可以直接在树上做差分序列的标记 后者打起来更舒适一点.. 具体实现: 先求x,y的lca,且dep[x]<dep[y] ...
- 在线倍增法求LCA专题
1.cojs 186. [USACO Oct08] 牧场旅行 ★★ 输入文件:pwalk.in 输出文件:pwalk.out 简单对比时间限制:1 s 内存限制:128 MB n个被自 ...
随机推荐
- nmon分析工具的使用
linux监控服务器资源 1.下载nmon_linux_more_14g.tar.gz,下载完成解压之后,我们先命令行看看自己Linux的版本,和nmon支持一下Linux发行版本 2.mkdir / ...
- Java thread(4)
这一块主要是讨论关于进程同步的相关问题,主要是考虑一下的关键字:锁对象.条件对象 -> synchronized wait() notify(). 1.关于锁对象与条件对象: 所对象的定义在ja ...
- 什么是php工厂模式
工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式.著名的Jive论坛 ,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见.今天我们就为大家介绍一下PHP中的 ...
- [Linux] 014 帮助命令
1. 帮助命令:man 命令名称:man 命令所在路径:/bin/man 执行权限:所有用户 语法:man [命令或配置文件] 功能描述:获得帮助信息 范例: 查看 ls 命令的帮助信息 $ man ...
- for in 和for of的区别
for in 和for of的区别:https://www.jianshu.com/p/c43f418d6bf0 1 遍历数组通常用for循环 ES5的话也可以使用forEach,ES5具有遍历数组功 ...
- Linux固定ip配置
第一步:查看网络信息 [root@localhost ~]# ifconfig ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu ...
- 【五一qbxt】day4 数论知识
这些东西大部分之前都学过了啊qwq zhx大概也知道我们之前跟着他学过这些了qwq,所以: 先讲新的东西qwq:(意思就是先讲我们没有学过的东西) 进制转换 10=23+21=1010(2) =32+ ...
- P4126 [AHOI2009]最小割(网络流+tarjan)
P4126 [AHOI2009]最小割 边$(x,y)$是可行流的条件: 1.满流:2.残量网络中$x,y$不连通 边$(x,y)$是必须流的条件: 1.满流:2.残量网络中$x,S$与$y,T$分别 ...
- 【JMeter4.0】二、JMeter4.0安装与配置
二.安装配置JMeter jmeter是一个纯java工具,因此,JDK必不可少,现在最新版的jmeter是4.0,建议使用1.8及以上的JDK安装配置JDK,如没有,请见:[JMeter4.0]一. ...
- 如何用latex画一个简单的表格
latex毫无疑问是一个十分强大的论文写作工具,所以掌握它就显得非常有意义,讲一下如何画一个简单的表格,代码如下: \begin{table}\centering\begin{tabular}{||c ...