hdu 2586 欧拉序+rmq 求lca
题意:求树上任意两点的距离
先说下欧拉序

对这颗树来说 欧拉序为 ABDBEGBACFHFCA 那欧拉序有啥用
这里先说第一个作用 求lca
对于一个欧拉序列,我们要求的两个点在欧拉序中的第一个位置之间肯定包含他们的lca,因为欧拉序1上任意两点之间肯定包含从第一个点走到第二个点访问的路径上的所有点
所以只需要记录他们的深度,然后从两个询问子节点x,y第一次出现的位置之间的深度最小值即可,可能不大好理解,看张图吧。

也就是说求lca可以转换为求一段区间的最值问题,结合rmq就可以处理啦
对于2586这题有个结论:树上任意两个点的距离等于两个点到根的距离之和减去2倍lca到根的距离
上代码
:
#include <cstdio>
#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
struct node
{
int x;
ll cost;
};
vector<node> edge[];
ll dis[];// 到根节点的距离
int dep[];
int ver[];// 欧拉序列
int first[];// 在欧拉序中第一次出现的位置
int vret;//
int n,m;
int mn[][];
void dfs(int x,int fa,int deep) // 求出欧拉序 以及每个点对应的度
{
ver[++vret]=x;
first[x]=vret;
dep[vret]=deep;
int len=edge[x].size();
for(int i=;i<len;i++)
{
node temp=edge[x][i];
if(temp.x!=fa)
{
dis[temp.x]=dis[x]+temp.cost;
dfs(temp.x,x,deep+);
ver[++vret]=x;
dep[vret]=deep; //
}
}
}
void st(int n)// 维护的是欧拉序 长度需要注意一下
{
int temp=(int)floor(log2(double(n)));
for(int i=;i<=n;i++) mn[i][]=i;// 注意一下 这里维护的是点 不是单纯的值
for(int j=;j<=temp;j++)
{
for(int i=;i+(<<j)-<=n;i++)
{
int a=mn[i][j-];
int b=mn[i+(<<(j-))][j-];
if(dep[a] < dep[b]) mn[i][j]=a;
else mn[i][j]=b;
}
}
}
int rmq(int x,int y)
{
int k=(int)(log(double(y-x+))/log(2.0));
int a=mn[x][k];
int b=mn[y-(<<k)+][k];
if(dep[a] < dep [b]) return a;
else return b;
}
int lca(int x,int y)
{
int fx=first[x];
int fy=first[y];
if(fx>fy) swap(fx,fy);
return rmq(fx,fy);
}
void init()
{
vret=;
dis[]=;
for(int i=;i<=n;i++) edge[i].clear();
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
init();// edge
scanf("%d %d",&n,&m);
for(int i=;i<n;i++)
{
int x,y;
ll cost;
scanf("%d %d %lld",&x,&y,&cost);
node temp;
temp.cost=cost;
temp.x=x;
edge[y].push_back(temp);
temp.x=y;
edge[x].push_back(temp);
} dfs(,,);//
st(*n-); for(int i=;i<=m;i++)
{
int x,y;
cin>>x>>y;
int temp=lca(x,y);// point
cout<<dis[x]+dis[y]-*dis[temp]<<endl;
}
}
return ;
}
hdu 2586 欧拉序+rmq 求lca的更多相关文章
- P3379 【模板】最近公共祖先(LCA)(欧拉序+rmq)
P3379 [模板]最近公共祖先(LCA) 用欧拉序$+rmq$维护的$lca$可以做到$O(nlogn)$预处理,$O(1)$查询 从这里剻个图 #include<iostream> # ...
- lca 欧拉序+rmq(st) 欧拉序+rmq(线段树) 离线dfs 倍增
https://www.luogu.org/problemnew/show/P3379 1.欧拉序+rmq(st) /* 在这里,对于一个数,选择最左边的 选择任意一个都可以,[left_index, ...
- dfs序+RMQ求LCA详解
首先安利自己倍增求LCA的博客,前置(算不上)知识在此. LCA有3种求法:倍增求lca(上面qwq),树链剖分求lca(什么时候会了树链剖分再说.),还有,标题. 是的你也来和我一起学习这个了qwq ...
- HDU 2586(LCA欧拉序和st表)
什么是欧拉序,可以去这个大佬的博客(https://www.cnblogs.com/stxy-ferryman/p/7741970.html)巨详细 因为欧拉序中的两点之间,就是两点遍历的过程,所以只 ...
- Bzoj 2286 & Luogu P2495 消耗战(LCA+虚树+欧拉序)
题面 洛谷 Bzoj 题解 很容易想到$O(nk)$的树形$dp$吧,设$f[i]$表示处理完这$i$颗子树的最小花费,同时再设一个$mi[i]$表示$i$到根节点$1$路径上的距离最小值.于是有: ...
- dfs序和欧拉序
生命不息,学习不止,昨天学了两个算法,总结一下,然而只是略懂,请路过的大佬多多谅解. 一.dfs序 1.什么是dfs序? 其实完全可以从字面意义上理解,dfs序就是指一棵树被dfs时所经过的节点的 ...
- RMQ求LCA
题目链接 rmq求LCA,interesting. 一直没有学这玩意儿是因为CTSC的Day1T2,当时我打的树剖LCA 65分,gxb打的rmq LCA 45分... 不过rmq理论复杂度还是小一点 ...
- LCA-RMQ+欧拉序
还是那一道洛谷的板子题来说吧 传送门 其实好几天之前就写了 结果dr实在是太弱了 没有那么多的精力 于是就一直咕咕咕了 哎 今天终于补上来了 LCA概念传送门 RMQ传送门 这个算法是基于RMQ和欧拉 ...
- BZOJ1906树上的蚂蚁&BZOJ3700发展城市——RMQ求LCA+树链的交
题目描述 众所周知,Hzwer学长是一名高富帅,他打算投入巨资发展一些小城市. Hzwer打算在城市中开N个宾馆,由于Hzwer非常壕,所以宾馆必须建在空中,但是这样就必须建立宾馆之间的连接通道.机智 ...
随机推荐
- Social GAN: Socially Acceptable Trajectories with Generative Adversarial Networks
Social GAN: Socially Acceptable Trajectories with Generative Adversarial Networks 2019-06-01 09:52:4 ...
- windows powershell学习
PowerShell,从名字可以知道,他首先是一个shell,shell的意思就是和Linux的bash等一样.和原来的cmd一样就是在里边敲命令(可执行文件)使用: 而Power就意味他是一个功能强 ...
- Oracle中的统计信息
一.什么是统计信息 统计信息主要是描述数据库中表,索引的大小,规模,数据分布状况等的一类信息.例如,表的行数,块数,平均每行的大小,索引的leaf blocks,索引字段的行数,不同值的大小等,都属于 ...
- The difference between a bad programmer and a good one is whether he considers his code or his data structures more important. Bad programmers worry about the code. Good programmers worry about data
重构:改善饿了么交易系统的设计思路 原创: 盛赫 阿里巴巴中间件 昨天
- win10下caffe+anaconda+python+Jupyter Notebooks安装流程
python3.5(推荐)或者python2.7 CUDA 8+ cuDNN5.1 python环境不能单独配置,必须先编译caffe,才能编译python环境. 下载caffe prebuild版本 ...
- ffmpeg-php扩展
php视频缩略图,较常用的是ffmpeg-php 1: 安装 ffmpeg ffmpeg的下载链接 http://ffmpeg.org/download.html 解压安装包 tar -jxvf f ...
- typescript属性类型接口
/* typeScript中的接口 - 1.属性类接口 */ /* 接口的作用:在面向对象的编程中,接口是一种规范的定义,它定义了行为和动作的规范,在程序设计里面,接口起到一种限制和规范的作用.接口定 ...
- 软件定义网络基础---SDN数据平面
主要介绍SDN架构和转发模型 一:传统网络设备 (一)传统设备控制平面和数据平面 (二)数据平面的任务 数据平面对数据包的处理,主要通过查询由控制平面所生成的转发信息表来完成 (三)传统网络数据平面数 ...
- QML按键
1.普通用法 import QtQuick 2.9 import QtQuick.Window 2.2 import QtQuick.Controls 2.2 ApplicationWindow { ...
- LeetCode_383. Ransom Note
383. Ransom Note Easy Given an arbitrary ransom note string and another string containing letters fr ...