什么是欧拉序,可以去这个大佬的博客(https://www.cnblogs.com/stxy-ferryman/p/7741970.html)巨详细

因为欧拉序中的两点之间,就是两点遍历的过程,所以只要找遍历过程中对应的最小的深度就行了,这里用st表存,first存第一个u出现的地方,用value存欧拉序,同时用depth存对应深度

模板

 struct node{
int v,next,dist;
}a[maxn<<];
int n,m,tot,len;
int st[maxn<<][], depth[maxn<<],value[maxn<<],first[maxn<<];
int dist[maxn],head[maxn];
void add(int u,int v,int dist0){
a[tot].next=head[u];
a[tot].dist=dist0;
a[tot].v=v;
head[u]=tot++;
}
void dfs(int u,int fa,int d) {
value[++len]=u;depth[len]=d;first[u]=len;
for (int i=head[u];~i;i=a[i].next){
int v=a[i].v;if(v==fa)continue;
dist[v]=dist[u]+a[i].dist;
dfs(v,u,d+);
value[++len]=u;depth[len]=d;
}
}
inline void init(int n){
for(int i=;i<=n;i++)head[i]=-,depth[i]=;
tot=,len=;
}
inline void makest(){
for(it i=;i<=len;i++)st[i][]=depth[i];
for(it i=;<<i<=len;i++){
for(it j=;j+(<<i)-<=len;j++){
st[j][i]=min(st[j][i-],st[j+(<<(i-))][i-]);
}
}
}
inline int dis(int u,int v){
int l=first[u],r=first[v];
if(l>r){swap(l,r);}
int k=log2(r-l+);
int dep=min(st[l][k],st[r-(<<k)+][k]);
return dist[u]+dist[v]-*dist[value[first[dep]]];
}

题意:

以1为根的树,两个点之间的最近距离是多少

思路:

模板LCA

用欧拉序+st表

 #include<bits/stdc++.h>
using namespace std;
#define ll long long
#define il inline
#define it register int
#define inf 0x3f3f3f3f
#define lowbit(x) (x)&(-x)
#define mem(a,b) memset(a,b,sizeof(a))
#define modd 998244353
const int maxn=4e4+;
struct node{
int v,next,dist;
}a[maxn<<];
int n,m,tot,len;
int st[maxn<<][], depth[maxn<<],value[maxn<<],first[maxn<<];
int dist[maxn],head[maxn];
void add(int u,int v,int dist0){
a[tot].next=head[u];
a[tot].dist=dist0;
a[tot].v=v;
head[u]=tot++;
}
void dfs(int u,int fa,int d) {
value[++len]=u;depth[len]=d;first[u]=len;
for (int i=head[u];~i;i=a[i].next){
int v=a[i].v;if(v==fa)continue;
dist[v]=dist[u]+a[i].dist;
dfs(v,u,d+);
value[++len]=u;depth[len]=d;
}
}
inline void init(int n){
for(int i=;i<=n;i++)head[i]=-,depth[i]=;
tot=,len=;
}
inline void makest(){
for(it i=;i<=len;i++)st[i][]=depth[i];
for(it i=;<<i<=len;i++){
for(it j=;j+(<<i)-<=len;j++){
st[j][i]=min(st[j][i-],st[j+(<<(i-))][i-]);
}
}
}
inline int dis(int u,int v){
int l=first[u],r=first[v];
if(l>r){swap(l,r);}
int k=log2(r-l+);
int dep=min(st[l][k],st[r-(<<k)+][k]);
return dist[u]+dist[v]-*dist[value[first[dep]]];
}
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
init(n);
for(it i=;i<n-;i++){int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);add(v,u,w);
}
dfs(,,);
makest();
while(m--){
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",dis(l,r));
}
}
return ;
}

用倍增

 #include<bits/stdc++.h>
using namespace std;
#define ll long long
#define il inline
#define it register int
#define inf 0x3f3f3f3f
#define lowbit(x) (x)&(-x)
#define mem(a,b) memset(a,b,sizeof(a))
#define modd 998244353
const int maxn=4e4+;
struct node{
int v,next,dist;
}a[maxn<<];
int n,m,tot;
int fath[maxn][], depth[maxn];
int dist[maxn],head[maxn];
void add(int u,int v,int dist0){
a[tot].next=head[u];
a[tot].dist=dist0;
a[tot].v=v;
head[u]=tot++;
}
void dfs(int u,int fa,int d) {
fath[u][]=fa; depth[u]=d;
for(int i=;i<;i++) fath[u][i]=fath[fath[u][i-]][i-];
for (int i=head[u];~i;i=a[i].next){
int v=a[i].v;if(v==fa)continue;
dist[v]=dist[u]+a[i].dist;
dfs(v,u,d+);
}
}
void init(int n){
for(int i=;i<=n;i++)fath[i][]=,dist[i]=,head[i]=-,depth[i]=;
tot=;
}
inline int lca(int x,int y){
if(depth[x]<depth[y])swap(x,y);
int h=depth[x]-depth[y];
for(it i=;h>;i++){
if(h&){
x=fath[x][i];
}
h>>=;
}
if(x==y)return x;
for(it i=;i>=;i--){
if(fath[x][i]!=fath[y][i]){
x=fath[x][i];
y=fath[y][i];
}
}
return fath[x][];
}
inline int dis(int u,int v){
int d=lca(u,v);
return dist[u]+dist[v]-*dist[d];
}
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
init(n);
for(it i=;i<n-;i++){int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);add(v,u,w);
}
dfs(,,);
while(m--){
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",dis(l,r));
}
}
return ;
}

HDU 2586(LCA欧拉序和st表)的更多相关文章

  1. lca 欧拉序+rmq(st) 欧拉序+rmq(线段树) 离线dfs 倍增

    https://www.luogu.org/problemnew/show/P3379 1.欧拉序+rmq(st) /* 在这里,对于一个数,选择最左边的 选择任意一个都可以,[left_index, ...

  2. HDU - 4548-美素数 (欧拉素数筛+打表)

    小明对数的研究比较热爱,一谈到数,脑子里就涌现出好多数的问题,今天,小明想考考你对素数的认识.  问题是这样的:一个十进制数,如果是素数,而且它的各位数字和也是素数,则称之为"美素数&quo ...

  3. hdu 2586 欧拉序+rmq 求lca

    题意:求树上任意两点的距离 先说下欧拉序 对这颗树来说 欧拉序为 ABDBEGBACFHFCA 那欧拉序有啥用 这里先说第一个作用 求lca 对于一个欧拉序列,我们要求的两个点在欧拉序中的第一个位置之 ...

  4. 【BZOJ3611】[Heoi2014]大工程 欧拉序+ST表+单调栈

    [BZOJ3611][Heoi2014]大工程 Description 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道.  我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶 ...

  5. Bzoj 2286 & Luogu P2495 消耗战(LCA+虚树+欧拉序)

    题面 洛谷 Bzoj 题解 很容易想到$O(nk)$的树形$dp$吧,设$f[i]$表示处理完这$i$颗子树的最小花费,同时再设一个$mi[i]$表示$i$到根节点$1$路径上的距离最小值.于是有: ...

  6. P3379 【模板】最近公共祖先(LCA)(欧拉序+rmq)

    P3379 [模板]最近公共祖先(LCA) 用欧拉序$+rmq$维护的$lca$可以做到$O(nlogn)$预处理,$O(1)$查询 从这里剻个图 #include<iostream> # ...

  7. dfs序和欧拉序

    生命不息,学习不止,昨天学了两个算法,总结一下,然而只是略懂,请路过的大佬多多谅解.   一.dfs序 1.什么是dfs序? 其实完全可以从字面意义上理解,dfs序就是指一棵树被dfs时所经过的节点的 ...

  8. LCA-RMQ+欧拉序

    还是那一道洛谷的板子题来说吧 传送门 其实好几天之前就写了 结果dr实在是太弱了 没有那么多的精力 于是就一直咕咕咕了 哎 今天终于补上来了 LCA概念传送门 RMQ传送门 这个算法是基于RMQ和欧拉 ...

  9. [BZOJ3772]精神污染 主席树上树+欧拉序

    3772: 精神污染 Time Limit: 10 Sec  Memory Limit: 64 MB Description 兵库县位于日本列岛的中央位置,北临日本海,南面濑户内海直通太平洋,中央部位 ...

随机推荐

  1. [LGR-054]洛谷10月月赛II

    浏览器 结论popcnt(x^y)和popcnt(x)+popcnt(y)的奇偶性相同. 然后就是popcnt为奇数的乘为偶数的.预处理一下\(2^{16}\)次方以内的popcnt,直接\(O(1) ...

  2. Docker最全教程——从理论到实战(十)

    终于按时完成第二篇.本来准备着手讲一些实践,但是数据库部分没有讲到,部分实践会存在一些问题,于是就有了此篇以及后续——数据库容器化.本篇将从SQL Server容器化实践开始,并逐步讲解其他数据库的容 ...

  3. 动态生成sku组合输入列表

    <!DOCTYPE html> <html> <head> <title></title> <meta http-equiv=&quo ...

  4. Vue组件中的Data为什么是函数。

    简单点说,组件是要复用的,在很多地方都会调用.   如果data不是函数,而是属性,就又可能会发生多个地方的相同组件操作同一个Data属性,导致数据混乱. 而如果是函数,因为组件data函数的返回值是 ...

  5. JUC-线程间通信

    面试题: 两个线程,一个线程打印1-52,另一个打印字母A-Z打印顺序为12A34B...5152Z, 要求用线程间通信 线程间通信:1.生产者+消费者2.通知等待唤醒机制 多线程编程模版中 1.判断 ...

  6. [Web安全]SQL注入

    Web网站最头痛的就是遭受攻击.Web很脆弱,所以基本的安防工作,我们必须要了解! 所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意 ...

  7. C语言中各数据类型(eg.int和float的区别)

  8. RGBA alpha 透明度混合算法

    RGBA alpha 透明度混合算法 .分类: 图像处理 Ps技术 2011-05-25 09:11 1112人阅读 评论(0) 收藏 举报 Alpha 透明度混合算法,网上收集整理,分成以下三种: ...

  9. 工具系列 | git checkout 可替换命令 git switch 和 git restore

    前言 git checkout 这个命令承担了太多职责,既被用来切换分支,又被用来恢复工作区文件,对用户造成了很大的认知负担. Git社区发布了Git的新版本2.23.在该版本中,有一个特性非常引人瞩 ...

  10. DE1+回顾

    本实验使用DE1器件,cyloneV,主要做的基础实验,目的是回顾前期的学习和巩固知识和熟悉操作流程. 视频主要学习的是小梅哥视频. 工程文件夹取名 prj -----   工程文件存放目录(ip文件 ...