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

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

模板

  1. struct node{
  2. int v,next,dist;
  3. }a[maxn<<];
  4. int n,m,tot,len;
  5. int st[maxn<<][], depth[maxn<<],value[maxn<<],first[maxn<<];
  6. int dist[maxn],head[maxn];
  7. void add(int u,int v,int dist0){
  8. a[tot].next=head[u];
  9. a[tot].dist=dist0;
  10. a[tot].v=v;
  11. head[u]=tot++;
  12. }
  13. void dfs(int u,int fa,int d) {
  14. value[++len]=u;depth[len]=d;first[u]=len;
  15. for (int i=head[u];~i;i=a[i].next){
  16. int v=a[i].v;if(v==fa)continue;
  17. dist[v]=dist[u]+a[i].dist;
  18. dfs(v,u,d+);
  19. value[++len]=u;depth[len]=d;
  20. }
  21. }
  22. inline void init(int n){
  23. for(int i=;i<=n;i++)head[i]=-,depth[i]=;
  24. tot=,len=;
  25. }
  26. inline void makest(){
  27. for(it i=;i<=len;i++)st[i][]=depth[i];
  28. for(it i=;<<i<=len;i++){
  29. for(it j=;j+(<<i)-<=len;j++){
  30. st[j][i]=min(st[j][i-],st[j+(<<(i-))][i-]);
  31. }
  32. }
  33. }
  34. inline int dis(int u,int v){
  35. int l=first[u],r=first[v];
  36. if(l>r){swap(l,r);}
  37. int k=log2(r-l+);
  38. int dep=min(st[l][k],st[r-(<<k)+][k]);
  39. return dist[u]+dist[v]-*dist[value[first[dep]]];
  40. }

题意:

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

思路:

模板LCA

用欧拉序+st表

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define ll long long
  4. #define il inline
  5. #define it register int
  6. #define inf 0x3f3f3f3f
  7. #define lowbit(x) (x)&(-x)
  8. #define mem(a,b) memset(a,b,sizeof(a))
  9. #define modd 998244353
  10. const int maxn=4e4+;
  11. struct node{
  12. int v,next,dist;
  13. }a[maxn<<];
  14. int n,m,tot,len;
  15. int st[maxn<<][], depth[maxn<<],value[maxn<<],first[maxn<<];
  16. int dist[maxn],head[maxn];
  17. void add(int u,int v,int dist0){
  18. a[tot].next=head[u];
  19. a[tot].dist=dist0;
  20. a[tot].v=v;
  21. head[u]=tot++;
  22. }
  23. void dfs(int u,int fa,int d) {
  24. value[++len]=u;depth[len]=d;first[u]=len;
  25. for (int i=head[u];~i;i=a[i].next){
  26. int v=a[i].v;if(v==fa)continue;
  27. dist[v]=dist[u]+a[i].dist;
  28. dfs(v,u,d+);
  29. value[++len]=u;depth[len]=d;
  30. }
  31. }
  32. inline void init(int n){
  33. for(int i=;i<=n;i++)head[i]=-,depth[i]=;
  34. tot=,len=;
  35. }
  36. inline void makest(){
  37. for(it i=;i<=len;i++)st[i][]=depth[i];
  38. for(it i=;<<i<=len;i++){
  39. for(it j=;j+(<<i)-<=len;j++){
  40. st[j][i]=min(st[j][i-],st[j+(<<(i-))][i-]);
  41. }
  42. }
  43. }
  44. inline int dis(int u,int v){
  45. int l=first[u],r=first[v];
  46. if(l>r){swap(l,r);}
  47. int k=log2(r-l+);
  48. int dep=min(st[l][k],st[r-(<<k)+][k]);
  49. return dist[u]+dist[v]-*dist[value[first[dep]]];
  50. }
  51. int main(){
  52. int t;
  53. scanf("%d",&t);
  54. while(t--){
  55. scanf("%d%d",&n,&m);
  56. init(n);
  57. for(it i=;i<n-;i++){int u,v,w;
  58. scanf("%d%d%d",&u,&v,&w);
  59. add(u,v,w);add(v,u,w);
  60. }
  61. dfs(,,);
  62. makest();
  63. while(m--){
  64. int l,r;
  65. scanf("%d%d",&l,&r);
  66. printf("%d\n",dis(l,r));
  67. }
  68. }
  69. return ;
  70. }

用倍增

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define ll long long
  4. #define il inline
  5. #define it register int
  6. #define inf 0x3f3f3f3f
  7. #define lowbit(x) (x)&(-x)
  8. #define mem(a,b) memset(a,b,sizeof(a))
  9. #define modd 998244353
  10. const int maxn=4e4+;
  11. struct node{
  12. int v,next,dist;
  13. }a[maxn<<];
  14. int n,m,tot;
  15. int fath[maxn][], depth[maxn];
  16. int dist[maxn],head[maxn];
  17. void add(int u,int v,int dist0){
  18. a[tot].next=head[u];
  19. a[tot].dist=dist0;
  20. a[tot].v=v;
  21. head[u]=tot++;
  22. }
  23. void dfs(int u,int fa,int d) {
  24. fath[u][]=fa; depth[u]=d;
  25. for(int i=;i<;i++) fath[u][i]=fath[fath[u][i-]][i-];
  26. for (int i=head[u];~i;i=a[i].next){
  27. int v=a[i].v;if(v==fa)continue;
  28. dist[v]=dist[u]+a[i].dist;
  29. dfs(v,u,d+);
  30. }
  31. }
  32. void init(int n){
  33. for(int i=;i<=n;i++)fath[i][]=,dist[i]=,head[i]=-,depth[i]=;
  34. tot=;
  35. }
  36. inline int lca(int x,int y){
  37. if(depth[x]<depth[y])swap(x,y);
  38. int h=depth[x]-depth[y];
  39. for(it i=;h>;i++){
  40. if(h&){
  41. x=fath[x][i];
  42. }
  43. h>>=;
  44. }
  45. if(x==y)return x;
  46. for(it i=;i>=;i--){
  47. if(fath[x][i]!=fath[y][i]){
  48. x=fath[x][i];
  49. y=fath[y][i];
  50. }
  51. }
  52. return fath[x][];
  53. }
  54. inline int dis(int u,int v){
  55. int d=lca(u,v);
  56. return dist[u]+dist[v]-*dist[d];
  57. }
  58. int main(){
  59. int t;
  60. scanf("%d",&t);
  61. while(t--){
  62. scanf("%d%d",&n,&m);
  63. init(n);
  64. for(it i=;i<n-;i++){int u,v,w;
  65. scanf("%d%d%d",&u,&v,&w);
  66. add(u,v,w);add(v,u,w);
  67. }
  68. dfs(,,);
  69. while(m--){
  70. int l,r;
  71. scanf("%d%d",&l,&r);
  72. printf("%d\n",dis(l,r));
  73. }
  74. }
  75. return ;
  76. }

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. swagger2使用

    添加依赖 <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swag ...

  2. nginx 简单理解和配置

    1.概念 Nginx是一个高性能的HTTP和反向代理的web服务器,同时也提供了IMAP/POP3/SMTP服务,Nginx是由伊戈尔·塞索耶夫为俄罗斯访问量第二的Rambler.ru站点开发的,第一 ...

  3. PP: Tripoles: A new class of relationships in time series data

    Problem: ?? mining relationships in time series data; A new class of relationships in time series da ...

  4. Docker学习一篇就够了

    Docker 1.简介 Docker是一个开源的应用容器引擎:是一个轻量级容器技术: Docker支持将软件编译成一个镜像:然后在镜像中各种软件做好配置,将镜像发布出去,其他使用者可以直接使用这个镜像 ...

  5. Python标准库之sys模块

    获取Python解释器的版本信息 import sys print(sys.version) #输出 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 17:00:18) ...

  6. Response与ServletContext对象

    HTTP协议: 请求消息:客户端发送给服务器端的数据 数据格式: 请求行: 格式: 请求方式 请求url 请求协议/版本 请求头:告诉服务器,当前访问的浏览器自身的一些信息 格式: 请求头名称: 请求 ...

  7. (原创)SpringBoot入门

    本文章是SpringBoot入门的介绍在这里   我会尽量写一些细节性的东西,我用的是IDEA2016  Tomcat7 JDK1.8 Maven3.3.9 IDEA Tomcat JDK Maven ...

  8. 环境配置 | mac环境变量文件.bash_profile相关

    每次环境配置都费老劲,零零碎碎的知识就记在这里 文件:~/.bash_profile

  9. jQuery操作css

    jQuery addClass() 方法 向被选中元素添加class属性,参数为属性值 $("div").addClass("imp"); 也可以同时向多个元素 ...

  10. Allegro 反射仿真--仿真设置

    一.打开BRD文件 打开PCB SI,启动Cadence Product Choices界面,如图1-1所示,一般我们选择Allegro PCB SI 630(SPECCTRAQuest),具体如下图 ...