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非常壕,所以宾馆必须建在空中,但是这样就必须建立宾馆之间的连接通道.机智 ...
随机推荐
- 制作 python解释器
https://www.zhihu.com/tardis/sogou/qus/27286136
- 蓝牙BLE: 蓝牙4.0 BLE广播数据解析(转)
BLE 设备工作的第一步就是向外广播数据.广播数据中带有设备相关的信息.本文主要说一下 BLE 的广播中的数据的规范以及广播包的解析. 1. 广播模式 BLE 中有两种角色 Central 和 Per ...
- NET 4.5 中新增的特性调用者信息特性CallerMemberNameAttribute/CallerFilePathAttribute/CallerLineNumberAttribute
标题中所说的三个特性 CallerMemberNameAttribute / CallerFilePathAttribute / CallerLineNumberAttribute 我们统称为调用者信 ...
- Oracle数据库启动报错,找不到数据文件(ORA-01157和ORA-01110)
数据库报了ORA-01157和ORA-01110错误,提示找不到一个数据文件. 1.启动数据库报错 在启动数据库过程中,报了ORA-01157和ORA-01110错误,提示找不到数据文件. SQL&g ...
- disruptor 单生产者多消费者
demo1 单生产者多消费者创建. maven 依赖 <!-- https://mvnrepository.com/artifact/com.lmax/disruptor --> < ...
- yii2增删改查操作
https://www.yiichina.com/tutorial/996 https://www.yiichina.com/tutorial/834 一.新增 使用model::save()操作进行 ...
- centos7.6下编译安装zabbix4.0.10长期支持版
一.安装数据库,这里使用的是percona-server5..24版本 配置如下 [root@zabbix4_clone:~]# cat /etc/my.cnf # Example MySQL con ...
- ISO/IEC 9899:2011 条款5——5.1 概念模型
5.1 概念模型 5.1.1 翻译环境 5.1.2 执行环境
- 实战二:LoadRunner创建一个测试脚本
问题一:执行脚本浏览器不能自动启动??? 原因:loadrunner11只支持IE9以下浏览器和火狐低版本浏览器 解决办法:1.IE浏览器取消勾选[启用第三方浏览器扩展]启动IE,从[工具]进入[In ...
- dart里面的时间处理:
原文地址:https://www.cnblogs.com/wyhlightstar/p/11059942.html 1.获取当前时间 var now = new DateTime.now(); pri ...