树剖 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 学习笔记
树链剖分 顾名思义,就是把一课时分成若干条链,使得它可以用数据结构(例如线段树)来维护 一些定义: 重儿子:子树最大的儿子 轻儿子:除了重儿子以外的儿子 重边:父节点与重儿子组成的边 轻边:除重边以外 ...
随机推荐
- Windows7运行无法记录历史命令问题解决
Windows7运行无法记录历史命令,每次都需要手动敲命令,解决方法如下: 1.任务栏中右键,选择"属性"菜单: 2.在弹出框中的"[开始]菜单"选项卡的隐私区 ...
- Environment中有大量访问目录的函数
public class Environment { /** * Return root of the "system" partition holding the core An ...
- JSON(2)JSONObject解析Josn和创建Jsonf示例
1.解析Json /* * test.josn内容如下: { "languages":[ {"id":"1","name" ...
- HUST 1698 - 电影院 组合数学 + 分类思想
http://acm.hust.edu.cn/problem/show/1698 题目就是要把一个数n分成4段,其中中间两段一定要是奇数. 问有多少种情况. 分类, 奇数 + 奇数 + 奇数 + 奇数 ...
- AngularJS ng-repeat下使用ng-model
1 2 3 blue:<input type="radio" value="1" ng-model="selectValue"/> ...
- ABP教程(三)- 开始一个简单的任务管理系统 – 后端编码
上一篇 我们介绍了什么是ABP,这一篇我们通过原作者的”简单任务系统”例子,演示如何运用ABP开发项目 创建实体 一般来说任务是需要分配给人来做的,所以我们创建两个实体模型类:Task和Persion ...
- 7.JAVA-类继承、覆写、final关键字
1.JAVA继承-extends 在java中,要想实现继承则使用extends关键字. 一般子类被称为派生类,父类称为基类(super) extends需要注意的地方: java不允许多重继承(一个 ...
- [BZOJ1088][SCOI2005]扫雷Mine DP
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1088 记录下每一个格子对应左边格子放的雷的情况,然后dp转移就好了. #include&l ...
- object -c OOP , 源码组织 ,Foundation 框架 详解1
object -c OOP , 源码组织 ,Foundation 框架 详解1 1.1 So what is OOP? OOP is a way of constructing softwar ...
- restful api的简单理解
百度百科的描述:一种软件架构风格,设计风格而不是标准,只是提供了一组设计原则和约束条件.它主要用于客户端和服务器交互类的软件.基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制. RES ...