树剖 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 学习笔记
树链剖分 顾名思义,就是把一课时分成若干条链,使得它可以用数据结构(例如线段树)来维护 一些定义: 重儿子:子树最大的儿子 轻儿子:除了重儿子以外的儿子 重边:父节点与重儿子组成的边 轻边:除重边以外 ...
随机推荐
- 题解报告:hdu 2709 Sumsets
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2709 Problem Description Farmer John commanded his co ...
- JAVA Android王牌教程
Java基础 在Java基础系列文章中,我将说明Java的基础内容,特别是面向对象的相关概念. Java基础01 从HelloWorld到面向对象 Java基础02 方法与数据成员 Java基础03 ...
- LD_LIBRARY_PATH与-L的关系以及延伸
最近跟同学讨论c++在编译时g++ -L.. 和LD_LIBRARY_PATH的问题,今天在做一个东西的时候发现,我对这两个东西的理解是错误的,经过一番研究,写下我对这些东西的想法,如果有不对的地方, ...
- Discrete Logging
Discrete Logging Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 5865 Accepted: 2618 ...
- Android拍照得到全尺寸图片并进行压缩/拍照或者图库选择 压缩后 图片 上传
http://www.jb51.net/article/77223.htm https://www.cnblogs.com/breeze1988/p/4019510.html
- web安全后渗透--XSS平台搭建及使用
xss平台搭建 1.申请一个云主机来进行建站:149.28.xx.xx 2.安装lnmp: wget http://soft.vpser.net/lnmp/lnmp1.5.tar.gz -cO ln ...
- java 线程池第一篇 之 ThreadPoolExcutor
一:什么是线程池? java 线程池是将大量的线程集中管理的类,包括对线程的创建,资源的管理,线程生命周期的管理.当系统中存在大量的异步任务的时候就考虑使用java线程池管理所有的线程.减少系统资源的 ...
- CREATE CONVERSION - 定义一个用户定义的码制转换
SYNOPSIS CREATE [DEFAULT] CONVERSION name FOR source_encoding TO dest_encoding FROM funcname DESCRIP ...
- at, batch, atq, atrm - 排队、检查或删除以后要执行的作业
总览 at [-V] [-q 队列] [-f 文件] [-mldbv] 时间 at -c 作业 [作业...] atq [-V] [-q 队列] [-v] atrm [-V] 作业 [作业...] b ...
- http 1.0 http 1.1 http 2.0的区别
HTTP/1.0 版的主要缺点是,每个TCP连接只能发送一个请求.发送数据完毕,连接就关闭,如果还要请求其他资源,就必须再新建一个连接. http1.1优点: 1.HTTP 1.1 版引入了持久连接( ...