树剖 lca



橙边为轻边
红边为重边
绿数为每个点的 top
橙数为每个点的编号
步骤
1 先预处理 每个点的 deep深度 size子树大小 dad父节点
2 再预处理 每个点的 top重链顶点
3 就是跳了
应用
洛谷 P2912 [USACO08OCT] 牧场散步
效率蛮高的
此题中用 len[i] 表示 i 到根距离
询问 x 和 y 的距离
答案可用 len[x] + len[y] - 2*len[ lca(x,y) ]表示
而 lca 可以用树剖求出
len[] 在树剖求lca 的预处理中 可以顺带求出来
树剖求 lca 虽然不常用
但它确实很吊
嘻嘻 我的 树剖代码 目前是本题 的 rank1
时间短 空间小
#include<bits/stdc++.h>
#define N 1003
using namespace std;
int cnt,head[N],to[N<<],dis[N<<],next[N<<],len[N],size[N],deep[N],dad[N],n,m,top[N];
int read(){//读入优化
char ch=getchar();
int ans=;
while(!isdigit(ch))ch=getchar();
while(isdigit(ch)){
ans=ans*+ch-'';
ch=getchar();
}
return ans;
}
int lca(int x,int y){//树剖求lca
for(;top[x]!=top[y];){
if(deep[top[x]]<deep[top[y]])x^=y^=x^=y;//利用二进制的 swap()
x=dad[top[x]];
}
if(deep[x]>deep[y])x^=y^=x^=y;
return x;
}
void dfs(int k){//步骤1
int v;
size[k]=,deep[k]=deep[dad[k]]+;
for(int i=head[k];i;i=next[i]){
v=to[i];
if(v!=dad[k])//各种预处理,包括针对本题的 len[]数组
len[v]=dis[i]+len[k],dad[v]=k,dfs(v),size[k]+=size[v];
}
} void dfs1(int k){//步骤2
int t=,v;
if(!top[k])top[k]=k;
for(int i=head[k];i;i=next[i]){
v=to[i];
if(v!=dad[k]&&size[t]<size[v])
t=v;
}
if(t)top[t]=top[k],dfs1(t);
for(int i=head[k];i;i=next[i]){
v=to[i];
if(v!=dad[k]&&v!=t)
dfs1(v);
}
}
int main(){
n=read(),m=read();
int x,y,z;
while(--n){
x=read(),y=read(),z=read();
next[++cnt]=head[x];
to[cnt]=y;
head[x]=cnt;
dis[cnt]=z;
next[++cnt]=head[y];
to[cnt]=x;
head[y]=cnt;
dis[cnt]=z;
}
dfs();
dfs1();
while(m--){
x=read(),y=read();
printf("%d\n",len[x]+len[y]-(len[lca(x,y)]<<));
}
return ;
}
树剖 lca的更多相关文章
- BZOJ_2286_[Sdoi2011]消耗战_虚树+树形DP+树剖lca
BZOJ_2286_[Sdoi2011]消耗战_虚树+树形DP Description 在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达.现在,我军已经侦查到敌军的 ...
- bzoj 3307: 雨天的尾巴【树剖lca+树上差分+线段树合并】
这居然是我第一次写线段树合并--所以我居然在合并的时候加点结果WAWAWAMLEMLEMLE--!ro的时候居然直接指到la就行-- 树上差分,每个点建一棵动态开点线段树,然后统计答案的时候合并即可 ...
- 树剖LCA讲解
LCA的类型多种多样,只说我知道的,就有倍增求LCA,tarjin求LCA和树链剖分求LCA,当然,也还有很多其他的方法. 其中最常用,速度最快的莫过于树链剖分的LCA了. 树链剖分,首先字面理解一下 ...
- 【BZOJ 3626】 [LNOI2014]LCA【在线+主席树+树剖】
题目链接: TP 题解: 可能是我比较纱布,看不懂题解,只好自己想了…… 先附一个离线版本题解[Ivan] 我们考虑对于询问区间是可以差分的,然而这并没有什么卵用,然后考虑怎么统计答案. 首先LC ...
- tarjan,树剖,倍增求lca
1.tarjan求lca 思想: void tarjan(int u,int f){ for(int i=---){//枚举边 if(v==f) continue; dfs(v); //继续搜 uni ...
- BZOJ 3626 [LNOI2014]LCA:树剖 + 差分 + 离线【将深度转化成点权之和】
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3626 题意: 给出一个n个节点的有根树(编号为0到n-1,根节点为0,n <= 50 ...
- POJ3417Network(LCA+树上查分||树剖+线段树)
Yixght is a manager of the company called SzqNetwork(SN). Now she's very worried because she has jus ...
- 【树剖求LCA】树剖知识点
不太优美但是有注释的版本: #include<cstdio> #include<iostream> using namespace std; struct edge{ int ...
- 树链剖分 树剖求lca 学习笔记
树链剖分 顾名思义,就是把一课时分成若干条链,使得它可以用数据结构(例如线段树)来维护 一些定义: 重儿子:子树最大的儿子 轻儿子:除了重儿子以外的儿子 重边:父节点与重儿子组成的边 轻边:除重边以外 ...
随机推荐
- windowsEvents
今天我们要实现这个关闭窗口的功能,就是点窗口的那个叉叉它会关闭. 设计窗口的事件就是WindowsEvents,而与之有关的监听器就是WindowsListener WindowsListener也是 ...
- 鼠标适配器Adapter
先来看看概念: 现在我们要写一个这样的东西,就是一个窗口,然后鼠标点一下就有一个小圆点,like this: 来我们来看代码: import java.awt.*; import java.util. ...
- 【LeetCode】297. Serialize and Deserialize Binary Tree
二叉树的序列化与反序列化. 如果使用string作为媒介来存储,传递序列化结果的话,会给反序列话带来很多不方便. 这里学会了使用 sstream 中的 输入流'istringstream' 和 输出流 ...
- HDU 5996 博弈
http://acm.hdu.edu.cn/showproblem.php?pid=5996 博弈论待补. 这题变化了一下,因为注意到奇数层的东西(层数从1开始),对手可以模仿地动,那就相当于没动. ...
- XML To Linq 读取Sharepoint列表中的附件列信息
通过页面查看,列表附件信息列的内容如下: var x = @"<div class='ExternalClass9936DCD1F074427B891D09CFCEFC2AB6'> ...
- mac系统 usr/ 目录下无法新建文件夹???
这个问题是在操作mongodb的时候遇到的,很苦恼.目前已经解决,将解决方法分享给各位遇到同样问题的你们. 1.重启电脑,开始关机就立马按住command+R,进入macOS恢复功能界面,进入的时间可 ...
- JavaScript——responseType
https://www.cnblogs.com/cdemo/p/5225848.html https://blog.csdn.net/wkyseo/article/details/78232485 异 ...
- webpack3整理(第一节/满三节)
一.css文件打包到js中(loader的三种写法) //第一种写法:直接用use. module: { rules: [{ test: /\.css$/, use: ['style-loader', ...
- 微信小程序中的图形验证码
可以在utils中新建一个mcaptcha.js 代码如下: module.exports = class Mcaptcha { constructor(options) { this.options ...
- CREATE SCHEMA - 定义一个新的模式
SYNOPSIS CREATE SCHEMA schemaname [ AUTHORIZATION username ] [ schema_element [ ... ] ] CREATE SCHEM ...