简述这几天的LCA 心得:

LCA有两种做法:离线 or 在线

先学的离线;

原理博客很多。

我写得两道题,已经模板。

HDU:http://acm.hdu.edu.cn/showproblem.php?pid=2586

HDU :http://acm.hdu.edu.cn/showproblem.php?pid=2874 2874;

之前一份板子:

  1. #pragma comment(linker, "/STACK:10240000000,10240000000")
  2.  
  3. #include<iostream>
  4. #include<stdio.h>
  5. #include<string.h>
  6. #include<cmath>
  7. #include<algorithm>
  8. #include<string>
  9. #include<vector>
  10. using namespace std;
  11.  
  12. #define N 51111
  13. struct node
  14. {
  15. int v,w;
  16.  
  17. node(int vv,int ww)
  18. {
  19. v=vv;
  20. w=ww;
  21. }
  22. };
  23. int f[N],dis[N],ans[N],vis[N],n;
  24. vector<node>mp[N];
  25. vector<node>q[N];
  26.  
  27. int find(int x)
  28. {
  29. if (f[x]!=x) f[x]=find(f[x]);
  30. return f[x];
  31. }
  32.  
  33. void lca(int u)
  34. {
  35. for (int i=;i<mp[u].size();i++)
  36. {
  37. int v=mp[u][i].v;
  38. if (vis[v]) continue;
  39. vis[v]=;
  40.  
  41. dis[v]=dis[u]+mp[u][i].w;
  42. lca(v);
  43. f[v]=u;
  44. for (int j=;j<q[v].size();j++)
  45. {
  46. int c=q[v][j].v;
  47. if (vis[c]&&ans[q[v][j].w]==-)
  48. {
  49. if (v==c) ans[q[v][j].w]=;
  50. else ans[q[v][j].w]=dis[v]+dis[c]-*dis[find(c)];
  51. }
  52. }
  53. }
  54. }
  55.  
  56. int main()
  57. {
  58. int T;
  59. scanf("%d",&T);
  60. while (T--)
  61. {
  62. int m;
  63. scanf("%d%d",&n,&m);
  64. for (int i=;i<=n;i++)
  65. {
  66. mp[i].clear();
  67. q[i].clear();
  68. ans[i]=-;
  69. f[i]=i;
  70. vis[i]=;
  71. }
  72. for (int i=;i<n;i++)
  73. {
  74. int a,b,c;
  75. scanf("%d%d%d",&a,&b,&c);
  76. mp[a].push_back(node(b,c));
  77. mp[b].push_back(node(a,c));
  78. }
  79. for (int i=;i<=m;i++)
  80. {
  81. int a,b;
  82. scanf("%d%d",&a,&b);
  83. q[a].push_back(node(b,i));
  84. q[b].push_back(node(a,i));
  85. }
  86. vis[]=;
  87. dis[]=;
  88. lca();
  89.  
  90. for (int i=;i<=m;i++)
  91. printf("%d\n",ans[i]);
  92. }
  93. return ;
  94. }

是有问题的,但是数据弱所以没爆出来。

正确形式:

  1. #include<iostream>
  2. #include<stdio.h>
  3. #include<string.h>
  4. #include<cmath>
  5. #include<algorithm>
  6. #include<string>
  7. #include<vector>
  8. using namespace std;
  9.  
  10. #define N 51111
  11. struct node
  12. {
  13. int v,w;
  14.  
  15. node(int vv,int ww)
  16. {
  17. v=vv;
  18. w=ww;
  19. }
  20. };
  21. int f[N],dis[N],ans[N],vis[N],n;
  22. vector<node>mp[N];
  23. vector<node>q[N];
  24.  
  25. int find(int x)
  26. {
  27. if (f[x]!=x) f[x]=find(f[x]);
  28. return f[x];
  29. }
  30.  
  31. void lca(int u)
  32. {
  33. for (int i=;i<mp[u].size();i++)
  34. {
  35. int v=mp[u][i].v;
  36. if (vis[v]) continue;
  37. vis[v]=;
  38.  
  39. dis[v]=dis[u]+mp[u][i].w;
  40. lca(v);
  41. f[v]=u;
  42. }
  43. for (int j=;j<q[u].size();j++)
  44. {
  45. int c=q[u][j].v;
  46. if (vis[c]&&ans[q[u][j].w]==-)
  47. {
  48. if (u==c) ans[q[u][j].w]=;
  49. else ans[q[u][j].w]=dis[u]+dis[c]-*dis[find(c)];
  50. }
  51. }
  52.  
  53. }
  54.  
  55. int main()
  56. {
  57. int T;
  58. scanf("%d",&T);
  59. while (T--)
  60. {
  61. int m;
  62. scanf("%d%d",&n,&m);
  63. for (int i=;i<=n;i++)
  64. {
  65. mp[i].clear();
  66. q[i].clear();
  67. ans[i]=-;
  68. f[i]=i;
  69. vis[i]=;
  70. }
  71. for (int i=;i<n;i++)
  72. {
  73. int a,b,c;
  74. scanf("%d%d%d",&a,&b,&c);
  75. mp[a].push_back(node(b,c));
  76. mp[b].push_back(node(a,c));
  77. }
  78. for (int i=;i<=m;i++)
  79. {
  80. int a,b;
  81. scanf("%d%d",&a,&b);
  82. q[a].push_back(node(b,i));
  83. q[b].push_back(node(a,i));
  84. }
  85. vis[]=;
  86. dis[]=;
  87. lca();
  88.  
  89. for (int i=;i<=m;i++)
  90. printf("%d\n",ans[i]);
  91. }
  92. return ;
  93. }

可以仔细体验差别。

因为 在其中吃了大亏。HDU 2874 (都是简单题)卡了三天 。想想算法没错 ,果然是板子的问题。

换一种写法也可以,询问在递归前面也可以。

  1. #include<iostream>
  2. #include<stdio.h>
  3. #include<string.h>
  4. #include<cmath>
  5. #include<algorithm>
  6. #include<string>
  7. #include<vector>
  8. using namespace std;
  9.  
  10. #define N 21111
  11. typedef long long ll;
  12. struct node
  13. {
  14. int v,w;
  15. node(int vv=,int ww=)
  16. {
  17. v=vv;
  18. w=ww;
  19. }
  20. };
  21.  
  22. int f[N];
  23. int ans[],dis[N];
  24. int vis[N],mark[N];
  25.  
  26. vector<node>mp[N];
  27. vector<node>q[N];
  28.  
  29. int find(int x)
  30. {
  31. if (f[x]!=x) f[x]=find(f[x]);
  32. return f[x];
  33. }
  34.  
  35. void lca(int u)
  36. {
  37.  
  38. for (int i=;i<q[u].size();i++)
  39. {
  40. int c=q[u][i].v;
  41. int w=q[u][i].w;
  42. if (vis[c]&&ans[w]==-&&mark[find(c)]!=)
  43. {
  44. ans[w]=dis[u]+dis[c]-*dis[find(c)];
  45. }
  46. }
  47.  
  48. for (int i=;i<mp[u].size();i++)
  49. {
  50. int v=mp[u][i].v;
  51. if (vis[v]) continue;
  52. vis[v]=;
  53. dis[v]=dis[u]+mp[u][i].w;
  54. lca(v);
  55. f[v]=u;
  56. /*
  57. for (int j=0;j<q[v].size();j++)
  58. {
  59. int c=q[v][j].v;
  60. int w=q[v][j].w;
  61. if (vis[c]&&ans[w]==-1&&mark[find(c)]!=1)
  62. {
  63. // if (v==c) ans[w]=0;
  64. // else
  65. ans[w]=dis[v]+dis[c]-2*dis[find(c)];
  66. }
  67. }
  68. */
  69.  
  70. }
  71. }
  72.  
  73. int main()
  74. {
  75. // freopen("input.txt","r",stdin);
  76. // freopen("output1.txt","w",stdout);
  77. int n,m,C;
  78. while (scanf("%d%d%d",&n,&m,&C)!=EOF)
  79. {
  80. for (int i=;i<=n;i++)
  81. {
  82. f[i]=i;
  83. mp[i].clear();
  84. q[i].clear();
  85. vis[i]=;
  86. dis[i]=;
  87. mark[i]=;
  88. }
  89. for (int i=;i<=C;i++) ans[i]=-;
  90. for (int i=;i<=m;i++)
  91. {
  92. int a,b,c;
  93. scanf("%d%d%d",&a,&b,&c);
  94. mp[a].push_back(node(b,c));
  95. mp[b].push_back(node(a,c));
  96. }
  97. for (int i=;i<=C;i++)
  98. {
  99. int a,b;
  100. scanf("%d%d",&a,&b);
  101. q[a].push_back(node(b,i));
  102. q[b].push_back(node(a,i));
  103. }
  104.  
  105. for (int i=;i<=n;i++)
  106. if (!vis[i])
  107. {
  108. vis[i]=;
  109. dis[i]=;
  110. lca(i);
  111. mark[i]=;
  112. }
  113.  
  114. for (int i=;i<=n;i++)
  115. for (int j=;j<q[i].size();j++)
  116. {
  117. int u=i;
  118. int v=q[i][j].v;
  119. int w=q[i][j].w;
  120. if (find(u)!=find(v)) ans[w]=-;
  121. }
  122.  
  123. for (int i=;i<=C;i++)
  124. if (ans[i]==-) printf("Not connected\n");
  125. else printf("%d\n",ans[i]);
  126.  
  127. }
  128. return ;
  129. }

LCA 笔记的更多相关文章

  1. 最近公共祖先算法LCA笔记(树上倍增法)

    Update: 2019.7.15更新 万分感谢[宁信]大佬,认认真真地审核了本文章,指出了超过五处错误捂脸,太尴尬了. 万分感谢[宁信]大佬,认认真真地审核了本文章,指出了超过五处错误捂脸,太尴尬了 ...

  2. 算法笔记--lca倍增算法

    算法笔记 模板: vector<int>g[N]; vector<int>edge[N]; ][N]; int deep[N]; int h[N]; void dfs(int ...

  3. 算法学习笔记:最近公共祖先(LCA问题)

    当我们处理树上点与点关系的问题时(例如,最简单的,树上两点的距离),常常需要获知树上两点的最近公共祖先(Lowest Common Ancestor,LCA).如下图所示: 2号点是7号点和9号点的最 ...

  4. 树的直径,LCA复习笔记

    前言 复习笔记第6篇. 求直径的两种方法 树形DP: dfs(y); ans=max( ans,d[x]+d[y]+w[i] ); d[x]=max( d[x],d[y]+w[i] ); int di ...

  5. 最近公共祖先(LCA)学习笔记 | P3379 【模板】最近公共祖先(LCA)题解

    研究了LCA,写篇笔记记录一下. 讲解使用例题 P3379 [模板]最近公共祖先(LCA). 什么是LCA 最近公共祖先简称 LCA(Lowest Common Ancestor).两个节点的最近公共 ...

  6. LCA学习笔记

    写在前面 目录 一.LCA的定义 二.暴力法求LCA 三.倍增法求LCA 四.树链剖分求LCA 五.LCA典型例题 题目完成度 一.LCA的定义 LCA指的是最近公共祖先.具体地,给定一棵有根树,若结 ...

  7. 关于LCA的倍增解法的笔记

    emmmmm近日刚刚学习了LCA的倍增做法,写一篇BLOG来加强一下印象w 首先 何为LCA? LCA“光辉”是印度斯坦航空公司(HAL)为满足印度空军需要研制的单座单发轻型全天候超音速战斗攻击机,主 ...

  8. LCA算法笔记

    LCA,最近公共祖先,实现有多种不同的方法,在树上的问题中有着广泛的应用,比如说树上的最短路之类. LCA的实现方法有很多,比如RMQ.树链剖分等. 今天来讲其中实现较为简单的三种算法: RMQ+时间 ...

  9. 倍增LCA学习笔记

    前言 ​ "倍增",作为一种二进制拆分思想,广泛用于各中算法,如\(ST\)表,求解\(LCA\)等等...今天,我们仅讨论用该思想来求解树上两个节点的\(LCA\)(最近公共祖先 ...

随机推荐

  1. delphi常用函数过程

    数据类型转化 1.1.         数值和字符串转化 Procedure Str(X [: Width [ : Decimals ]]; var S); 将数值X按照一定格式转化成字符串S.Wid ...

  2. Oracle 11g 执行计划管理1

    1. 执行计划管理的工作原理 1.1控制执行计划的稳定性 11g之前,可以使用存储大纲(stored outline)和SQL Profile来固定某条SQL语句的执行计划,防止由于执行计划发生变化而 ...

  3. IOS下载资源zip到本地然后读取

    思路是 1.ios下载服务器上的zip资源包(图片,声音等经过zip压缩的资源包)到本地 2.解压zip到程序目录 3.从程序目录加载资源文件 一.下载zip资源 [cpp]-(NSString*)D ...

  4. selenium+python登录登出百度,等待页面加载,鼠标定位

    #coding:gbk from selenium import webdriver from selenium.webdriver.common.keys import Keys from sele ...

  5. 实战MySQL集群,试用CentOS 6下的MariaDB-Galera集成版

    说起mysql的集群估计很多人会首先想起mysql自带的replication或者mysql-mmm.mysql-mmm其实也是基于mysql自带的replication的,不过封装的更好用一些,但是 ...

  6. 使用eclipse开发

    Eclipse下载地址:http://www.eclipse.org/ 下载后进行解压缩,点击eclipse.exe即可使用eclipse workspace:工作区      Project:项目 ...

  7. java 命令对象简单学习实现:

    命令模式:首先我们要知道命令模式的基本定义:来自客户端的请求传入一个对象,从而使你可用不同的请求对客户进行参数化.用于“行为请求者”与“行为实现者”解耦,可实现二者之间的松耦合,以便适应变化.分离变化 ...

  8. [Environment Build] Win10下Appach配置

    1. Apache下载,登录http://httpd.apache.org/download.cgi,选择Files for Microsoft Windows, 有以下几个选择, 我选择的是Apac ...

  9. 九度oj 1528 最长回文子串

    原题链接:http://ac.jobdu.com/problem.php?pid=1528 小白书上的做法,不过这个还要简单些... #include<algorithm> #includ ...

  10. Mac下如何显示隐藏文件/文件夹_百度经验

    在应用程序里打开终端, cd 你的文件夹名 ls -a 即可显示该文件夹下的所有隐藏文件   如果你想打开整个系统的隐藏文件可以在终端下输入以下命令: defaults write com.apple ...