Distance Queries
Time Limit: 2000MS   Memory Limit: 30000K
Total Submissions: 11304   Accepted: 3985
Case Time Limit: 1000MS

Description

Farmer John's cows refused to run in his marathon since he chose a path much too long for their leisurely lifestyle. He therefore wants to find a path of a more reasonable length. The input to this problem consists of the same input as in "Navigation Nightmare",followed by a line containing a single integer K, followed by K "distance queries". Each distance query is a line of input containing two integers, giving the numbers of two farms between which FJ is interested in computing distance (measured in the length of the roads along the path between the two farms). Please answer FJ's distance queries as quickly as possible! 

Input

* Lines 1..1+M: Same format as "Navigation Nightmare"

* Line 2+M: A single integer, K. 1 <= K <= 10,000

* Lines 3+M..2+M+K: Each line corresponds to a distance query and contains the indices of two farms.

Output

* Lines 1..K: For each distance query, output on a single line an integer giving the appropriate distance. 

Sample Input

  1. 7 6
  2. 1 6 13 E
  3. 6 3 9 E
  4. 3 5 7 S
  5. 4 1 3 N
  6. 2 4 20 W
  7. 4 7 2 S
  8. 3
  9. 1 6
  10. 1 4
  11. 2 6

Sample Output

  1. 13
  2. 3
  3. 36
    学习LCA的好文章:http://taop.marchtea.com/04.04.html
    离线:将所有查询输入完毕后再统一输出结果。
    在线:查询一个输出一个。
  4.  
  5. dfs+并查集,离线
  1. #include <cstdio>
  2. #include <vector>
  3. using namespace std;
  4. const int MAXN=;
  5. int n,m,k;
  6. struct Edge{
  7. int to,w;
  8. Edge(){}
  9. Edge(int to,int w)
  10. {
  11. this->to=to;
  12. this->w=w;
  13. }
  14. };
  15. vector<Edge> arc[MAXN];
  16.  
  17. struct Node{
  18. int to,id;
  19. Node(){}
  20. Node(int to,int id)
  21. {
  22. this->to=to;
  23. this->id=id;
  24. }
  25. };
  26. vector<Node> que[MAXN];
  27.  
  28. int par[MAXN];
  29. void prep()
  30. {
  31. for(int i=;i<MAXN;i++)
  32. {
  33. d[i]=;
  34. vis[i]=;
  35. par[i]=i;
  36. }
  37. }
  38. int fnd(int x)
  39. {
  40. if(par[x]==x)
  41. {
  42. return x;
  43. }
  44. return par[x]=fnd(par[x]);
  45. }
  46. void unite(int fa,int son)
  47. {
  48. int a=fnd(fa);
  49. int b=fnd(son);
  50. par[b]=a;
  51. }
  52.  
  53. int vis[MAXN],d[MAXN];
  54. int res[MAXN];
  55. void tarjan(int u)
  56. {
  57. vis[u]=;
  58. for(int i=,size=que[u].size();i<size;i++)
  59. {
  60. Node nod=que[u][i];
  61. if(vis[nod.to])
  62. {
  63. int lca=fnd(nod.to);
  64. res[nod.id]=d[nod.to]+d[u]-*d[lca];
  65. }
  66. }
  67. for(int i=,size=arc[u].size();i<size;i++)
  68. {
  69. Edge e=arc[u][i];
  70. if(!vis[e.to])
  71. {
  72. d[e.to]=d[u]+e.w;
  73. tarjan(e.to);
  74. unite(u,e.to);
  75. }
  76. }
  77. }
  78. int main()
  79. {
  80. while(scanf("%d%d",&n,&m)!=EOF)
  81. {
  82. prep();
  83. for(int i=;i<=n;i++) arc[i].clear();
  84. for(int i=;i<m;i++)
  85. {
  86. int u,v,w;
  87. scanf("%d %d %d %*c",&u,&v,&w);
  88. arc[u].push_back(Edge(v,w));
  89. arc[v].push_back(Edge(u,w));
  90. }
  91. scanf("%d",&k);
  92. for(int i=;i<k;i++)
  93. {
  94. int u,v;
  95. scanf("%d%d",&u,&v);
  96. que[v].push_back(Node(u,i));
  97. que[u].push_back(Node(v,i));
  98. }
  99. for(int i=;i<=n;i++)
  100. {
  101. if(!vis[i])
  102. {
  103. tarjan(i);
  104. }
  105. }
  106. for(int i=;i<k;i++)
  107. {
  108. printf("%d\n",res[i]);
  109. }
  110. }
  111. return ;
  112. }
  1. 模板:RMQLCA在线算法(稀疏表实现RMQ)
  1. #include <cstdio>
  2. #include <cstring>
  3. #include <vector>
  4. #include <math.h>
  5. #include <algorithm>
  6. using namespace std;
  7. const int MAXN=;
  8. int n,m,k;
  9. struct Edge{
  10. int to,w;
  11. Edge(){}
  12. Edge(int to,int w)
  13. {
  14. this->to=to;
  15. this->w=w;
  16. }
  17. };
  18. vector<Edge> arc[MAXN];
  19.  
  20. int vs[MAXN+MAXN],depth[MAXN+MAXN],first[MAXN],tot;
  21. int d[MAXN],vis[MAXN];
  22. void dfs(int u,int dep)
  23. {
  24. vis[u]=;
  25. vs[++tot]=u;
  26. depth[tot]=dep;
  27. first[u]=tot;
  28. for(int i=,size=arc[u].size();i<size;i++)
  29. {
  30. Edge e=arc[u][i];
  31. if(!vis[e.to])
  32. {
  33. d[e.to]=d[u]+e.w;
  34. dfs(e.to,dep+);
  35. vs[++tot]=u;
  36. depth[tot]=dep;
  37. }
  38. }
  39. }
  40.  
  41. int dp[MAXN+MAXN][];
  42. void init_st(int size)
  43. {
  44. for(int i=;i<=size;i++) dp[i][]=i;
  45. for(int j=;j<;j++)
  46. {
  47. for(int i=;i<=size;i++)
  48. {
  49. if(i+(<<j)-<=size)
  50. {
  51. int a=dp[i][j-];
  52. int b=dp[i+(<<(j-))][j-];
  53. dp[i][j]=depth[a]<depth[b]?a:b;
  54. }
  55. }
  56. }
  57. }
  58. int rmq_st(int l,int r)
  59. {
  60. int limit=(int)(log(r-l+1.0)/(log(2.0)));
  61. int a=dp[l][limit];
  62. int b=dp[r-(<<limit)+][limit];
  63. return depth[a]<depth[b]?a:b;
  64. }
  65.  
  66. int LCA(int u,int v)
  67. {
  68. if(first[u]>first[v]) swap(u,v);
  69. int id=rmq_st(first[u],first[v]);
  70. return vs[id];
  71. }
  72.  
  73. int main()
  74. {
  75. while(scanf("%d%d",&n,&m)!=EOF)
  76. {
  77. tot=;
  78. memset(vis,,sizeof(vis));
  79. memset(d,,sizeof(d));
  80. for(int i=;i<=n;i++) arc[i].clear();
  81. for(int i=;i<m;i++)
  82. {
  83. int u,v,w;
  84. scanf("%d %d %d %*c",&u,&v,&w);
  85. arc[u].push_back(Edge(v,w));
  86. arc[v].push_back(Edge(u,w));
  87. }
  88. for(int i=;i<=n;i++)
  89. {
  90. if(!vis[i])
  91. {
  92. dfs(i,);
  93. }
  94. }
  95. init_st(tot);
  96. scanf("%d",&k);
  97. for(int i=;i<k;i++)
  98. {
  99. int u,v;
  100. scanf("%d%d",&u,&v);
  101. int lca=LCA(u,v);
  102. int res=d[u]+d[v]-*d[lca];
  103. printf("%d\n",res);
  104. }
  105. }
  106. return ;
  107. }
  1.  

POJ1986(LCA应用:求两结点之间距离)的更多相关文章

  1. hdoj 1869 六度分离【最短路径求两两边之间最长边】

    六度分离 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  2. 求两个数之间的质数 -----------基于for循环 算法思想

    前端代码: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.as ...

  3. js求连个数之间的数字

    整理出自项目中一个需求,求两个数之间的数字. const week = function(arr,arr2){ let a=parseInt(arr); let b=parseInt(arr2); l ...

  4. 「POJ-3608」Bridge Across Islands (旋转卡壳--求两凸包距离)

    题目链接 POJ-3608 Bridge Across Islands 题意 依次按逆时针方向给出凸包,在两个凸包小岛之间造桥,求最小距离. 题解 旋转卡壳的应用之一:求两凸包的最近距离. 找到凸包 ...

  5. 求两点之间距离 C++

    求两点之间距离(20 分) 定义一个Point类,有两个数据成员:x和y, 分别代表x坐标和y坐标,并有若干成员函数. 定义一个函数Distance(), 用于求两点之间的距离.输入格式: 输入有两行 ...

  6. 旋转卡壳求两个凸包最近距离poj3608

    #include <iostream> #include <cmath> #include <vector> #include <string.h> # ...

  7. JavaScript求两个数字之间所有数字的和

    这是在fcc上的中级算法中的第一题,拉出来的原因并不是因为有什么好说的,而是我刚看时以为是求两个数字的和, 很显然错了.我感觉自己的文字理解能力被严重鄙视了- -.故拉出来折腾折腾. 要求: 给你一个 ...

  8. GPS(2)关于位置的3个示例,实时获取GPS定位数据,求两个经纬点距离,邻近某个区域圆时警告

    实时获取GPS定位数据 import android.app.Activity; import android.content.Context; import android.location.Loc ...

  9. js 求两个日期之间相差天数

    //求两个日期之间的相差天数 function daysBetween(DateOne, DateTwo) { var OneMonth = DateOne.substring(5, DateOne. ...

随机推荐

  1. JavaScript--基于对象的脚本语言学习笔记(一)

    1.两种嵌入js的方式    使用javascript前缀构建url:<a href="javascript:alert('执行JavaScript. .')">执行j ...

  2. web翻译——插件

    很多时候,可能我们web项目中需要的只是机械式的翻译,并不需要什么利用xml或者js json等等实现逼真翻译,那样工作量太大.这时候可能你就需要这几款小工具来帮助你.当然,如果 对翻译或者你的项目外 ...

  3. hdu 5538 House Building(长春现场赛——水题)

    题目链接:acm.hdu.edu.cn/showproblem.php?pid=5538 House Building Time Limit: 2000/1000 MS (Java/Others)   ...

  4. programming review (c++): (3)graph, binary search

    I.graph #include <iostream> #include <vector> using namespace std; vector<vector<, ...

  5. java jdbc 同时操作查询删除操作

    Connection conn = null;        try {            // 创建连接实例            conn = JdbcUtility.GetFactory() ...

  6. 关于eclipse 插件的挂载

    学习java的时候,不喜欢myeclipse 这种插件,什么都准备好了,自己动手就少了,不利于自己学习,现在我就diy 自己选几个插件来用,基本上就是 eclipse 加上我自己要用的插件,插件的安装 ...

  7. 【网络与系统安全】20179209 利用metasploit对windows系统的渗透

    这次实验的主角是素有"内网杀手"之称的metasploit.还是少说一些夸赞它的话(因为即使功能再强大,不明白它的原理,不会灵活使用它集成的功能,一样没有用),我们直入主题.简单说 ...

  8. JavaScript演示如何访问Search字段

    <!DOCTYPE html> <html> <body> <h3>演示如何访问Search字段</h3> <input type=& ...

  9. PHP Framework

    PHP Framework is built for PHP developers who need elegant toolkit to create full-featured web appli ...

  10. Java基础教程:多线程基础(4)——Lock的使用

    Java基础教程:多线程基础(4)——Lock的使用 快速开始 Java 5中Lock对象的也能实现同步的效果,而且在使用上更加方便. 本节重点的2个知识点是:ReentrantLock类的使用和Re ...