http://codevs.cn/problem/2370/

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int M=5e4+;
  4. const int N=;
  5. struct node{
  6. int v,w;
  7. node(int vv=,int ww=):v(vv),w(ww){}
  8. };
  9. vector<node>e[M];
  10. int n,grand[M][N],dis[M][N],deep[M],book[M],root,s;
  11. void dfs(int u){
  12. for(int i=;i<=s;i++){
  13. grand[u][i]=grand[grand[u][i-]][i-];
  14. dis[u][i]=dis[u][i-]+dis[grand[u][i-]][i-];
  15. if(!grand[u][i])
  16. break;
  17. }
  18. for(int i=;i<e[u].size();i++){
  19. int v=e[u][i].v;
  20. if(v!=grand[u][]){
  21. grand[v][]=u;
  22. deep[v]=deep[u]+;
  23. dis[v][]=e[u][i].w;
  24. dfs(v);
  25. }
  26. }
  27. }
  28. void init(){
  29. s=floor(log(1.0*n)/log(2.0));
  30. deep[]=-;
  31. dfs(root);
  32. }
  33. int LCA(int a,int b){
  34. if(deep[a]>deep[b])
  35. swap(a,b);
  36. int ans=;
  37. for(int i=s;i>=;i--){
  38. if(deep[a]<deep[b]&&deep[a]<=deep[grand[b][i]])
  39. ans+=dis[b][i],b=grand[b][i];
  40. }
  41. for(int i=s;i>=;i--){
  42. if(grand[a][i]!=grand[b][i])
  43. ans+=dis[a][i],ans+=dis[b][i],a=grand[a][i],b=grand[b][i];
  44. }
  45. if(a!=b)
  46. ans+=dis[a][]+dis[b][];
  47. return ans;
  48. }
  49. int main(){
  50.  
  51. scanf("%d",&n);
  52. for(int i=;i<n;i++){
  53. int u,v,w;
  54. scanf("%d%d%d",&u,&v,&w);
  55. u++;
  56. v++;///fu
  57. book[u]=;
  58. e[u].push_back(node(v,w));
  59. e[v].push_back(node(u,w));
  60. }
  61. for(int i=;i<=n;i++){
  62. if(!book[i]){
  63. root=i;
  64. break;
  65. }
  66. }
  67. init();
  68. int m;
  69. scanf("%d",&m);
  70. while(m--){
  71. int u,v;
  72. scanf("%d%d",&u,&v);
  73. u++,v++;
  74. printf("%d\n",LCA(u,v));
  75. }
  76. return ;
  77. }

http://codevs.cn/problem/1036/

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<vector>
  6. #include<cmath>
  7. using namespace std;
  8. const int M=3e4+;
  9. const int N=;
  10. struct node{
  11. int v,w;
  12. node(int vv=,int ww=):v(vv),w(ww){}
  13. };
  14. vector<node>e[M];
  15. int s,grand[M][N],dis[M][N],book[M],deep[M],root,n;
  16. void dfs(int u){
  17. for(int i=;i<=s;i++){
  18. grand[u][i]=grand[grand[u][i-]][i-];
  19. dis[u][i]=dis[u][i-]+dis[grand[u][i-]][i-];
  20. if(!grand[u][i])
  21. break;
  22. }
  23. for(int i=;i<e[u].size();i++){
  24. int v=e[u][i].v;
  25. if(v!=grand[u][]){
  26. grand[v][]=u;
  27. deep[v]=deep[u]+;
  28. dis[v][]=e[u][i].w;
  29. dfs(v);
  30. } // cout<<"!!"<<endl;
  31. }
  32. }
  33. void init(){
  34. s=floor(log(1.0*n)/log(2.0));
  35. deep[]=-;
  36. dfs(root);
  37. }
  38. int LCA(int a,int b){
  39. if(deep[a]>deep[b])
  40. swap(a,b);
  41. int ans=;
  42. for(int i=s;i>=;i--){
  43. if(deep[b]>deep[a]&&deep[a]<=deep[grand[b][i]])
  44. ans+=dis[b][i],b=grand[b][i];
  45. }
  46. for(int i=s;i>=;i--)
  47. if(grand[a][i]!=grand[b][i])
  48. ans+=dis[a][i]+dis[b][i],b=grand[b][i],a=grand[a][i];
  49. if(a!=b)
  50. ans+=dis[a][]+dis[b][];
  51. return ans;
  52. }
  53. int main(){
  54.  
  55. scanf("%d",&n);
  56. for(int i=;i<n;i++){
  57. int u,v;
  58. scanf("%d%d",&u,&v);
  59. book[v]=;
  60. e[u].push_back(node(v,));
  61. e[v].push_back(node(u,));
  62. }
  63. for(int i=;i<=n;i++)
  64. if(!book[i]){
  65. root=i;
  66. break;
  67. }
  68.  
  69. init();
  70. int m,u,v;
  71. scanf("%d",&m);
  72. scanf("%d",&u);
  73. int ans=;
  74. for(int i=;i<m;i++){
  75. scanf("%d",&v);
  76. ans+=LCA(u,v);
  77. u=v;
  78. }
  79. printf("%d\n",ans);
  80. return ;
  81. }

http://oj.fjaxyz.com:3389/problem.php?id=223
当LCA(a,b)==a时才能参赛

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<vector>
  6. #include<cmath>
  7. using namespace std;
  8. typedef long long ll;
  9. const int M=1e4+;
  10. struct node{
  11. int v;
  12. ll w;
  13. node(int vv=,ll ww=):v(vv),w(ww){}
  14. };
  15. vector<node>e[M];
  16. int grand[M][],s,n,root,deep[M];
  17. ll dis[M][],num,numt;
  18. void dfs(int u){
  19. for(int i=;i<=s;i++){
  20. grand[u][i]=grand[grand[u][i-]][i-];
  21. dis[u][i]=dis[u][i-]+dis[grand[u][i-]][i-];
  22. if(!grand[u][i])
  23. break;
  24. }
  25. for(int i=;i<e[u].size();i++){
  26. int v=e[u][i].v;
  27. if(v!=grand[u][]){
  28. grand[v][]=u;
  29. deep[v]=deep[u]+;
  30. dis[v][]=e[u][i].w;
  31. dfs(v);
  32. }
  33. }
  34. }
  35. void init(){
  36. s=floor(log(1.0*n)/log(2.0));
  37. deep[]=-;
  38. dfs(root);
  39. }
  40. void LCA(int u,int v){
  41. int a=u,b=v;
  42. if(deep[a]>deep[b])
  43. swap(a,b) ;
  44. ll ans=;
  45. for(int i=s;i>=;i--){
  46. if(deep[b]>deep[a]&&deep[a]<=deep[grand[b][i]])
  47. ans+=dis[b][i],b=grand[b][i];
  48. }
  49. for(int i=s;i>=;i--){
  50. if(grand[b][i]!=grand[a][i])
  51. ans+=dis[b][i]+dis[a][i],a=grand[a][i],b=grand[b][i];
  52. }
  53. if(a!=b)
  54. ans+=dis[a][]+dis[b][],a=grand[a][],b=grand[b][];
  55. if(a!=u)
  56. return ;
  57. // cout<<"!!"<<endl;
  58.  
  59. numt+=ans;
  60. num++;
  61. }
  62. int main(){
  63. int m;
  64. scanf("%d%d",&n,&m);
  65. for(int i=;i<n;i++){
  66. int u,v,w;
  67. scanf("%d%d%d",&u,&v,&w);
  68. e[u].push_back(node(v,w));
  69. e[v].push_back(node(u,w));
  70. }
  71. root=;
  72. init();
  73. while(m--){
  74. int u,v;
  75. scanf("%d%d",&u,&v);
  76.  
  77. LCA(u,v);
  78. }
  79. printf("%d\n",num);
  80. printf("%d\n",numt);
  81.  
  82. return ;
  83. }

zoj 3198

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3320

吐槽一下输出格式,言不表意!!

题意:求用最小权值的路径连接起3个节点,问这些路径的和;

分析,答案就是俩俩之间路径和/2;

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #include<vector>
  5. #include<cmath>
  6. using namespace std;
  7. const int M=5e4+;
  8. struct node{
  9. int v,w;
  10. node(int vv,int ww):v(vv),w(ww){}
  11. };
  12. vector<node>e[M];
  13. int grand[M][],dis[M][],deep[M],root,s,n,book[M];
  14. void dfs(int u){
  15. for(int i=;i<=s;i++){
  16. grand[u][i]=grand[grand[u][i-]][i-];
  17. dis[u][i]=dis[grand[u][i-]][i-]+dis[u][i-];
  18. if(!grand[u][i])
  19. break;
  20. }
  21. for(int i=;i<e[u].size();i++){
  22. int v=e[u][i].v;
  23. if(v!=grand[u][]){
  24. grand[v][]=u;
  25. deep[v]=deep[u]+;
  26. dis[v][]=e[u][i].w;
  27. dfs(v);
  28. }
  29. }
  30. }
  31. void init(){
  32. s=floor(log(1.0*n)/log(2.0));
  33. deep[]=-;
  34. dfs(root);
  35. }
  36. int LCA(int a,int b){
  37. if(deep[a]>deep[b])
  38. swap(a,b);
  39. int ans=;
  40. for(int i=s;i>=;i--){
  41. if(deep[a]<deep[b]&&deep[a]<=deep[grand[b][i]])
  42. ans+=dis[b][i],b=grand[b][i];
  43. }
  44. for(int i=s;i>=;i--){
  45. if(grand[a][i]!=grand[b][i])
  46. ans+=dis[a][i]+dis[b][i],a=grand[a][i],b=grand[b][i];
  47. }
  48. if(a!=b)
  49. ans+=dis[a][]+dis[b][];
  50. return ans;
  51. }
  52. int main(){
  53. int flag=;
  54. while(~scanf("%d",&n)&&n){
  55. if(flag)
  56. flag=;
  57. else
  58. printf("\n");
  59. for(int i=;i<=n;i++){
  60. e[i].clear();
  61. deep[i]=;
  62. book[i]=;
  63. for(int j=;j<=;j++)
  64. grand[i][j]=dis[i][j]=;
  65.  
  66. }
  67. for(int i=;i<n;i++){
  68. int u,v,w;
  69. scanf("%d%d%d",&u,&v,&w);
  70. u++;
  71. v++;
  72. book[v]=;
  73. e[u].push_back(node(v,w));
  74. e[v].push_back(node(u,w));
  75. }
  76. for(int i=;i<=n;i++){
  77. if(!book[i]){
  78. root=i;
  79. break;
  80. }
  81. }
  82. init();
  83. int m;
  84. scanf("%d",&m);
  85. while(m--){
  86. int u,v,k;
  87. scanf("%d%d%d",&u,&v,&k);
  88. u++,v++,k++;
  89. int ans=;
  90. ans+=LCA(u,v);
  91. // cout<<LCA(u,v)<<"~~~~~~~~1"<<endl;
  92. ans+=LCA(u,k);
  93. // cout<<LCA(u,k)<<"~~~~~~~~2"<<endl;
  94. ans+=LCA(v,k);
  95. // cout<<LCA(k,v)<<"~~~~~~~~3"<<endl;
  96. printf("%d\n",ans/);
  97. }
  98.  
  99. }
  100. return ;
  101. }

可用倍增LCA解题的更多相关文章

  1. [板子]倍增LCA

    倍增LCA板子,没有压行,可读性应该还可以.转载请随意. #include <cstdio> #include <cstring> #include <algorithm ...

  2. 洛谷P3128 [USACO15DEC]最大流Max Flow [倍增LCA]

    题目描述 Farmer John has installed a new system of  pipes to transport milk between the  stalls in his b ...

  3. Gym100685G Gadget Hackwrench(倍增LCA)

    题目大概说一棵边有方向的树,q个询问,每次询问结点u是否能走到v. 倍增LCA搞即可: 除了par[k][u]表示u结点往上走2k步到达的结点, 再加上upp[k][u]表示u结点往上走2k步经过边的 ...

  4. Codeforces 418d Big Problems for Organizers [树形dp][倍增lca]

    题意: 给你一棵有n个节点的树,树的边权都是1. 有m次询问,每次询问输出树上所有节点离其较近结点距离的最大值. 思路: 1.首先是按照常规树形dp的思路维护一个子树节点中距离该点的最大值son_di ...

  5. hdu 4674 Trip Advisor(缩点+倍增lca)

    花了一天半的时间,才把这道题ac= = 确实是道好题,好久没敲这么长的code了,尤其是最后的判定,各种销魂啊~ 题目中给出的条件最值得关注的就是:每个点最多只能在一个环内->原图是由一个个边连 ...

  6. Tsinsen A1505. 树(张闻涛) 倍增LCA,可持久化线段树,DFS序

    题目:http://www.tsinsen.com/A1505 A1505. 树(张闻涛) 时间限制:1.0s   内存限制:512.0MB    总提交次数:196   AC次数:65   平均分: ...

  7. codevs 1036 商务旅行 (倍增LCA)

    /* 在我还不知道LCA之前 暴力跑的SPFA 70分 三个点TLE */ #include<iostream> #include<cstdio> #include<cs ...

  8. hdu 2586 How far away ?倍增LCA

    hdu 2586 How far away ?倍增LCA 题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2586 思路: 针对询问次数多的时候,采取倍增 ...

  9. 洛谷P4180 [Beijing2010组队]次小生成树Tree(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)

    洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...

随机推荐

  1. libcurl在windows下的使用

    curl在linux下很好用,但到了windows下写程序却没办法使用了,这时候可以使用libcurl库 libcurl库的编译网上很多,我就不一一赘述了,curl的官方网站:https://curl ...

  2. 【Gson】网页上String获取的Json数据转化为对象

    1.网络上获取的String Json格式转化为对象获取数据: 需要的包:Gson Maven依赖: <!-- https://mvnrepository.com/artifact/com.go ...

  3. 吴裕雄--天生自然ShellX学习笔记:Shell 基本运算符

    Shell 和其他编程语言一样,支持多种运算符,包括: 算数运算符 关系运算符 布尔运算符 字符串运算符 文件测试运算符 原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 ...

  4. DAO层使用mybatis框架有关实体类的有趣细节

    1.根据个人习惯,将储存那些数据库查询结果集有映射关系的实体类的Package包名有如下格式: cn.bjut.domain cn.bjut.pojo cn.bjut.model cn.bjut.en ...

  5. Android巩固之事件分发机制

    https://www.cnblogs.com/liaojie970/p/5869152.html onTouchEvent是真正用来进行业务逻辑处理的地方,返回true表示已经将该事件消费,返回fa ...

  6. c语言中多维数组和指针的关系

    如图: 执行结果: 说明:由执行结果可知,三个输出的结果相等(可能在不同的平台执行结果不相同,但三个的结果是相等的),数组multi的地址与数组multi[0]的地址相同,都等于存储的第一个整数的地址 ...

  7. php中openssl_pkey_get_private()函数遇到false的问题 解决办法

    今天用openssl_pkey_get_private()函数遇到了一个大坑: 如果你的私钥文件(private_key.pem)是 -----BEGIN PRIVATE KEY-----字符串字符串 ...

  8. 1. Ruby基础知识

    1. Ruby执行选项 符号 作用 -c 检查代码正确性 -w 警告模式运行 -e 字面脚本 -l 行模式运行 单独 ruby -c Hello.rb 组合 ruby -le 'print " ...

  9. gff文件提取cds

    #!/usr/bin/perl use strict; use warnings; ########input######## ];my $cut = &cut($gff);my %cut = ...

  10. keras猫狗大战

    先划分数据集程序训练集中猫狗各12500张现在提取1000张做为训练集,500张作为测试集,500张作为验证集: # -*- coding: utf-8 -*-import os, shutil or ...