题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586

最近公共祖先问题~~LAC离散算法

题目大意:一个村子里有n个房子,这n个房子用n-1条路连接起来,接下了有m次询问,每次询问两个房子a,b之间的距离是多少。

很明显的最近公共祖先问题,先建一棵树,然后求出每一点i到树根的距离dis[i],然后每次询问a,b之间的距离=dis[a]+dis[b]-2*dis[LCA(a,b)];

LCA(a,b)即是a,b的最近公共祖先。。

关于最近公共祖先,给大家推荐一个学长的博客http://www.cnblogs.com/ylfdrib/archive/2010/11/03/1867901.html,里面讲的很不错!!

  1. # include<stdio.h>
  2. # include<string.h>
  3. # define N
  4. # define M
  5. struct node{
  6. int from,to,next,val;
  7. }edge[*N];
  8. struct node1{
  9. int from,to,next,num;
  10. }edge1[*M];
  11. int tol,head[N],head1[N],tol1,father[N],dis[N],LCA[M],n,m;
  12. bool visit[N];
  13. void add(int a,int b,int c)
  14. {
  15. edge[tol].from=a;edge[tol].to=b;edge[tol].next=head[a];edge[tol].val=c;head[a]=tol++;
  16. }
  17. void add1(int a,int b,int c)
  18. {
  19. edge1[tol1].from=a;edge1[tol1].to=b;edge1[tol1].next=head1[a];edge1[tol1].num=c;head1[a]=tol1++;
  20. }
  21. int find(int x)
  22. {
  23. if(x!=father[x])
  24. father[x]=find(father[x]);
  25. return father[x];
  26. }
  27. void tarjan(int u)
  28. {
  29. int j,v;
  30. visit[u]=;
  31. father[u]=u;
  32. //////////////////
  33. for(j=head1[u];j!=-;j=edge1[j].next)
  34. {
  35. v=edge1[j].to;
  36. if(visit[v]) LCA[edge1[j].num]=find(v);
  37. }
  38. //////////////////
  39. for(j=head[u];j!=-;j=edge[j].next)
  40. {
  41. v=edge[j].to;
  42. if(!visit[v])
  43. {
  44. dis[v]=dis[u]+edge[j].val;
  45. tarjan(v);
  46. father[v]=u;
  47. }
  48. }
  49. }
  50. int main()
  51. {
  52. int i,ncase,a,b,c;
  53. scanf("%d",&ncase);
  54. while(ncase--)
  55. {
  56. scanf("%d%d",&n,&m);
  57. tol=;
  58. memset(head,-,sizeof(head));
  59. for(i=;i<n;i++)
  60. {
  61. scanf("%d%d%d",&a,&b,&c);
  62. add(a,b,c);
  63. add(b,a,c);
  64. }
  65. memset(visit,,sizeof(visit));
  66. tol1=;
  67. memset(head1,-,sizeof(head1));
  68. for(i=;i<=m;i++)
  69. {
  70. scanf("%d%d",&a,&b);
  71. add1(a,b,i);
  72. add1(b,a,i);
  73. }
  74. ///LCA是一种离线算法,所以刚开始需要把所有的询问都输入,然后用邻接表进行存储,i表示第i次询问
  75. dis[]=;
  76. tarjan();
  77. for(i=;i<tol1;i+=)
  78. {
  79. a=edge1[i].from;
  80. b=edge1[i].to;
  81. c=edge1[i].num;
  82. printf("%d\n",dis[a]+dis[b]-*dis[LCA[c]]);
  83. }
  84. }
  85. return ;
  86. }

**************************

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. #include <vector>
  5. using namespace std;
  6.  
  7. const int NN=;
  8.  
  9. int n,m;
  10. vector<pair<int,int> > edge[NN],qe[NN];
  11. vector<int> q1,q2;
  12.  
  13. int p[NN];
  14. int find(int x)
  15. {
  16. if (p[x]!=x) p[x]=find(p[x]);
  17. return p[x];
  18. }
  19.  
  20. int sum=,ans[NN],dis[NN];
  21. bool vis[NN]={};
  22. void lca(int u,int fa)
  23. {
  24. p[u]=u;
  25. for (int i=; i<edge[u].size(); i++)
  26. {
  27. int v=edge[u][i].first;
  28. if (v==fa) continue;
  29. dis[v]=dis[u]+edge[u][i].second;
  30. lca(v,u);
  31. p[v]=u;
  32. }
  33. vis[u]=true;
  34. if (sum==m) return;
  35. for (int i=; i<qe[u].size(); i++)
  36. {
  37. int v=qe[u][i].first;
  38. if (vis[v])
  39. ans[qe[u][i].second]=dis[u]+dis[v]-*dis[find(v)];
  40. }
  41. }
  42.  
  43. int main()
  44. {
  45. int u,v,w;
  46.  
  47. int t;
  48. scanf("%d",&t);
  49. while(t--){
  50. scanf("%d%d",&n,&m);
  51. for (int i=; i<=n; i++)
  52. {
  53. edge[i].clear();
  54. }
  55. for (int i=; i<n; i++)
  56. {
  57. scanf("%d%d%d",&u,&v,&w);
  58. edge[u].push_back(make_pair(v,w));
  59. edge[v].push_back(make_pair(u,w));
  60. }
  61.  
  62. for (int i=; i<m; i++)
  63. {
  64. scanf("%d%d",&u,&v);
  65. qe[u].push_back(make_pair(v,i));
  66. qe[v].push_back(make_pair(u,i));
  67. ans[i]=;
  68. }
  69. dis[]=;
  70. lca(,);
  71. for (int i=; i<m; i++) printf("%d\n",ans[i]);
  72. }
  73. return ;
  74. }

hdu - 2586 How far away ?(最短路共同祖先问题)的更多相关文章

  1. HDU - 2586 How far away ?(LCA模板题)

    HDU - 2586 How far away ? Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & ...

  2. hdu 2586 How far away ?倍增LCA

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

  3. LCA(最近公共祖先)--tarjan离线算法 hdu 2586

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

  4. hdu 2586(最近公共祖先LCA)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 思路:在求解最近公共祖先的问题上,用到的是Tarjan的思想,从根结点开始形成一棵深搜树,非常好 ...

  5. HDU 2586 How far away? LCA 转化成RMQ

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 [题意] 给出一个N 个和N-1条边的连通图,询问任意两点间的距离.N<=40000 . [分 ...

  6. HDU 2586

    http://acm.hdu.edu.cn/showproblem.php?pid=2586 题意:求最近祖先节点的权值和 思路:LCA Tarjan算法 #include <stdio.h&g ...

  7. hdu 2586 How far away

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

  8. HDU 2586 (LCA模板题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2586 题目大意:在一个无向树上,求一条链权和. 解题思路: 0 | 1 /   \ 2      3 ...

  9. HDU 5637 Transform 单源最短路

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5637 题意: http://bestcoder.hdu.edu.cn/contests/contes ...

随机推荐

  1. css3部分属性兼容性别扭写法(因为很多我就叫他别扭了,希望全面早早支持css3吧)

    /*圆角class,需要设置圆角的元素加上class名称*/ .roundedCorners{ -webkit-border-radius: 10px;/*webkit内核浏览器*/ -moz-bor ...

  2. DataTable Javascript Link not working on 2nd page

    $(document).ready(function () { var otable = $('#tbl-resources').dataTable( { bJQueryUI: false, bFil ...

  3. windows xp sp3 下载地址

      windows xp service pack 3/ windows xp sp3 简体中文版下载地址: http://download.windowsupdate.com/msdownload/ ...

  4. WCF部署在IIS上

    WCF部署在IIS上 环境vs2010,WCF应用程序.如何将WCF部署在IIS上. 第一步:右键点击项目,选择生成部署包. 第二步:在你项目所在的文件目录下找到Package文件夹,这就是我们的部署 ...

  5. YaHoo Web优化的14条法则

    Web应用性能优化黄金法则:先优化前端程序(front-end)的性能,因为这是80%或以上的最终用户响应时间的花费所在. 法则1. 减少HTTP请求次数 80%的最终用户响应时间花在前端程序上,而其 ...

  6. C#中几种数据库的大数据批量插入

    C#语言中对SqlServer.Oracle.SQLite和MySql中的数据批量插入是支持的,不过Oracle需要使用Orace.DataAccess驱动. IProvider里有一个用于实现批量插 ...

  7. json处理三部曲之第二曲:利用Jackson处理json

    利用Jackson处理json需要导入的jar包(2以上版本的): <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.c ...

  8. NEU OJ 1644 Median I

    优先级队列 #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> ...

  9. 编译cvaux错误的原因

    引用:   http://www.cnblogs.com/oskycar/archive/2009/08/30/1556920.html VS2013 在debug模式下编译cvaux时会提示三个错误 ...

  10. POJ 1611 The Suspects(简单并查集)

    ( ̄▽ ̄)" #include<iostream> #include<cstdio> using namespace std; ]; void makeSet(int ...