1. /*********--LCA模板--***************/
  2. //设置好静态参数并构建好图的邻接表,然后调用lca_setquery()设置查询
  3. //最后调用lca_start(),在lca::dfs中的your code处理每次查询
  4. //复杂度O(M+Q)
  5. //表示图的邻接表
  6.  
  7. #define N 40100
  8. #define MAX_Q 200
  9.  
  10. struct node
  11. {
  12. int to,next,w;
  13. }edge[*N];
  14.  
  15. int pre[N],cnt;
  16.  
  17. int ans[MAX_Q];
  18.  
  19. void add_edge(int u,int v,int w)
  20. {
  21. edge[cnt].w = w;
  22. edge[cnt].to = v;
  23. edge[cnt].next =pre[u];
  24. pre[u] = cnt++;
  25. }
  26.  
  27. struct LCA
  28. {
  29. int ln;//表示图中的点,默认范围为[1,n]
  30. int bin[N],bw[N]; // 并查集 与 bw记录到根节点的深度
  31. struct node1
  32. {
  33. int to,next;
  34. int id;
  35. }edge1[MAX_Q*];
  36. int pre1[N],cnt1;
  37. int lmark[N];
  38.  
  39. void init(int n)//初始化传入点的个数n
  40. {
  41. ln = n;
  42. cnt1 = ;
  43. memset(pre1,-,sizeof(pre1));
  44. memset(lmark,,sizeof(lmark));
  45. for(int i=;i<=n;i++)
  46. bin[i] = i;
  47. }
  48.  
  49. void add_edge1(int u,int v,int id)
  50. {
  51. edge1[cnt1].id = id;//查询的id
  52. edge1[cnt1].to = v;
  53. edge1[cnt1].next = pre1[u];
  54. pre1[u]=cnt1++;
  55. }
  56.  
  57. int find(int v)
  58. {
  59. if(bin[v]==v) return v;
  60. return bin[v]=find(bin[v]);
  61. }
  62.  
  63. void lca_setquery(int m)
  64. {
  65. //把所有的查询加入
  66. //add_edge1(a,b);
  67. //add_edge1(b,a);
  68. for(int i=;i<m;i++)
  69. {
  70. int a,b;
  71. scanf("%d%d",&a,&b);
  72. add_edge1(a,b,i);
  73. add_edge1(b,a,i);
  74. }
  75. }
  76.  
  77. void dfs(int s,int w,int fa)
  78. {
  79. bw[s]=w;
  80. for(int p=pre[s];p!=-;p=edge[p].next)
  81. {
  82. int v=edge[p].to;
  83. if(v == fa) continue;//不到父亲节点
  84. if(lmark[v]==)
  85. {
  86. //dfs(v,w+1,s);
  87. dfs(v,w+edge[p].w,s);
  88. bin[v]=s;
  89. }
  90. }
  91. lmark[s] = ;
  92. //遍历需要查询的点对
  93. for(int p=pre1[s];p!=-;p=edge1[p].next)
  94. {
  95. int v = edge1[p].to;
  96. if(lmark[v] == )//这个点已经处理过了
  97. {
  98. int x = find(v); //最近公共祖先
  99. int dis = bw[v]-bw[x]+bw[s]-bw[x];//两点之间在树上最近距离(这里默认树边为1)
  100. // your code
  101. //ans[ edge1[p].id ] = dis;
  102. //
  103. }
  104. }
  105.  
  106. }
  107.  
  108. void lca_start()
  109. {
  110. dfs(,,-);//第一个参数表示根节点
  111. }
  112.  
  113. }lca;
  114.  
  115. //给出大小为n的树,查询m次两点最短距离
  116. //int main()
  117. //{
  118. // int T;
  119. // cin>>T;
  120. // while(T--)
  121. // {
  122. // int n,m;
  123. // scanf("%d%d",&n,&m);
  124. // cnt = 0;
  125. // memset(pre,-1,sizeof(pre));
  126. // for(int i=1;i<n;i++)
  127. // {
  128. // int a,b,c;
  129. // scanf("%d%d%d",&a,&b,&c);
  130. // add_edge(a,b,c);
  131. // add_edge(b,a,c);
  132. // }
  133. //
  134. // lca.init(n);
  135. // lca.lca_setquery(m);
  136. // lca.lca_start();
  137. // for(int i=0;i<m;i++) printf("%d\n",ans[i]);
  138. // }
  139. // return 0;
  140. //}

2.LCA 在线建立rmq(nlog(n)) 查询(log(n))

  1. #define N 40040
  2. #define LN 20
  3. struct node
  4. {
  5. int to,next;
  6. }edge[*N];
  7.  
  8. int cnt,pre[N];
  9.  
  10. void add_edge(int u,int v)
  11. {
  12. edge[cnt].to = v;
  13. edge[cnt].next = pre[u];
  14. pre[u] = cnt++;
  15. }
  16.  
  17. struct Lca_Online
  18. {
  19. int _n;
  20. int deep[N];
  21. int dp[N][LN];
  22. void _dfs(int s,int fa,int dd)
  23. {
  24. deep[s] = dd;
  25. for(int p=pre[s];p!=-;p=edge[p].next)
  26. {
  27. int v = edge[p].to;
  28. if(v == fa) continue;
  29. _dfs(v,s,dd+);
  30. dp[v][] = s;
  31. }
  32. }
  33.  
  34. void _init()
  35. {
  36. for(int j=;(<<j)<=_n;j++)
  37. {
  38. for(int i=;i<=_n;i++)
  39. {
  40. if(dp[i][j-]!=-) dp[i][j] = dp[ dp[i][j-] ][j-];
  41. }
  42. }
  43. }
  44. void lca_init(int n)
  45. {
  46. _n = n;
  47. memset(dp,-,sizeof(dp));
  48. //_dfs(firstid,-1,0);
  49. _dfs(,-,);
  50. _init();
  51. }
  52.  
  53. int lca_query(int a,int b)
  54. {
  55. if(deep[a]>deep[b]) swap(a,b);
  56. //调整b到a的同一高度
  57. for(int i=LN-;deep[b]>deep[a];i--)
  58. if(deep[b]-(<<i) >= deep[a]) b = dp[b][i];
  59. if(a == b) return a;
  60. for(int i=LN-;i>=;i--)
  61. {
  62. if(dp[a][i]!=dp[b][i]) a = dp[a][i],b = dp[b][i];
  63. }
  64. return dp[a][];
  65. }
  66. }lca;
  67.  
  68. //int d[N];
  69. //int main(int argc, const char * argv[]) {
  70. // int T;
  71. // cin>>T;
  72. // while(T--)
  73. // {
  74. // memset(d,0,sizeof(d));
  75. // cnt = 0;
  76. // memset(pre,-1,sizeof(pre));
  77. // int n;
  78. // scanf("%d",&n);
  79. // for(int i=1;i<n;i++)
  80. // {
  81. // int a,b;
  82. // scanf("%d%d",&a,&b);
  83. // add_edge(a, b);
  84. // add_edge(b, a);
  85. // d[b]++;
  86. // }
  87. // for(int i=1;i<=n;i++)
  88. // {
  89. // if(d[i] == 0) firstid = i;
  90. // }
  91. // int a,b;
  92. // cin>>a>>b;
  93. // lca.lca_init(n);
  94. // printf("%d\n",lca.lca_query(a, b));
  95. // }
  96. // return 0;
  97. //}

LCA模板的更多相关文章

  1. 倍增求lca模板

    倍增求lca模板 https://www.luogu.org/problem/show?pid=3379 #include<cstdio> #include<iostream> ...

  2. HDU 2586——How far away ?——————【LCA模板题】

    How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  3. 算法复习——LCA模板(POJ1330)

    题目: Description A rooted tree is a well-known data structure in computer science and engineering. An ...

  4. hdu 2586 How far away?(LCA模板题+离线tarjan算法)

    How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  5. LCA模板(数剖实现)

    题目链接:https://www.luogu.org/problemnew/show/P3379 题意:LCA模板题. 思路:今天开始学树剖,先拿lca练练.树剖解lca,两次dfs复杂度均为O(n) ...

  6. POJ 1330 Nearest Common Ancestors(LCA模板)

    给定一棵树求任意两个节点的公共祖先 tarjan离线求LCA思想是,先把所有的查询保存起来,然后dfs一遍树的时候在判断.如果当前节点是要求的两个节点当中的一个,那么再判断另外一个是否已经访问过,如果 ...

  7. HDU2586 How far away ?(LCA模板题)

    题目链接:传送门 题意: 给定一棵树,求两个点之间的距离. 分析: LCA 的模板题目 ans = dis[u]+dis[v] - 2*dis[lca(u,v)]; 在线算法:详细解说 传送门 代码例 ...

  8. 最近公共祖先(LCA)模板

    以下转自:https://www.cnblogs.com/JVxie/p/4854719.html 首先是最近公共祖先的概念(什么是最近公共祖先?): 在一棵没有环的树上,每个节点肯定有其父亲节点和祖 ...

  9. HDU 2586 How far away ?(LCA模板 近期公共祖先啊)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 Problem Description There are n houses in the vi ...

随机推荐

  1. jdk 与jre的区别

    jdk就是java的开发工具集,顾名思义就是你做开发用的,其中包括javac,也就是java compiler等. jre(java runtime environment),就是java程序的运行环 ...

  2. extjs 中动态给gridpanel 复选框赋值

    最近在搞extjs时需要动态根据数据给gridpanel的复选框赋值 网上看了很多 ,多不行,最后找到一个好使的方法 如下: RBACformPanel.getSelectionModel().sel ...

  3. Uniform Generator 分类: HDU 2015-06-19 23:26 11人阅读 评论(0) 收藏

    Uniform Generator Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) T ...

  4. python-day6 常见算法 python内置模块

    1.冒泡排序 需求:请按照从小到大对列表 [13, 22, 6, 99, 11] 进行排序 原理:相邻两个值进行比较,将较大的值放在右侧,依次比较! li=[39,11,43,88,765,9]for ...

  5. Python学习笔记-Day3-python内置函数

    python内置函数 1.abs    求绝对值 2.all 判断迭代器中的所有数据是否都为true 如果可迭代的数据的所有数据都为true或可迭代的数据为空,返回True.否则返回False 3.a ...

  6. 【Java】Float计算不准确

    大家可能都遇到过,float在计算某些值时,会有不准确的情况. 比如如下情况: > 计算不准确 package com.nicchagil.study.java.demo.No10float计算 ...

  7. shell与kernel的理解 转载

    Shell 的英文释义是外壳,与 kernel 内核名词遥相呼应,一外一内,一壳一核.内核就像瑞士银行的金库,存放着客户的黄金等众多的(硬件)资产,闲杂人等(包括客户)当然是严格禁止入内的,而作为客户 ...

  8. 如何从MySQL官方Yum仓库安装MySQL5.6

    (一),2013年10月,MySQL开发团队正式宣布支持Yum仓库,这就意味着我们现在可以从这个Yum库中获得最新和最优版的MySQL安装包.本文将在一台全新安装的CentOS6上安装MySQL5.6 ...

  9. C#读写本地ini

    //读写INI public class GF_INI { [DllImport("kernel32")] private static extern long WritePriv ...

  10. [SAP ABAP开发技术总结]Function远程、同步、异步调用

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...