这道题与之前那两道模板题不同的是,路径有了权值,而且边是双向的,root已经给出来了,就是1,(这个地方如果还按之前那样来计算入度是会出错的。数据里会出现多个root。。。数据地址可以在poj的discuss板块看到)。两个节点之间的距离,可以这样处理:先处理出每个节点i到根的距离dist[i],则节点a,b之间的距离就是dist[a]+dist[b]-2*dist[LCA(a,b)],或者是在LCA的过程中加一个形式变量来传递距离值(目测这样效率会更高)。我一开始是想的仅传递每层的距离,具体怎样记不清了,结果样例就华丽丽地wa了。个人认为这个题目描述真心不爽。最后那个方向字符在这个题中没用。

  1. #include<cstdio>
  2. #include<vector>
  3. #include<string>
  4. //sba,just predeal the distance between every node and the root.and the dist[u][v]=dist[u][root]+dist[v][root]-2*dist[x][root]
  5. using namespace std;
  6. ;
  7. ;
  8. ;
  9. struct node{
  10. int v,dis;
  11. node(){v=;dis=;}
  12. };
  13. int ansque[MAXQUERY];
  14. int father[MAXN];//i's ancestor and the distance between the son and the ancestor
  15. vector<node>map[MAXN];
  16. vector<node>query[MAXN];
  17. int dist[MAXN];//i -->root
  18. bool visit[MAXN],visit2[MAXN];
  19. int getfather(int v){
  20. if(father[v]==v)return v;
  21. return father[v]=getfather(father[v]);
  22. }
  23. void aunion(int u,int v){
  24. int fu=father[u],fv=father[v],di;
  25. father[fv]=fu;
  26. }
  27. void LCA(int id,int distance){
  28. int len=map[id].size();
  29. int son;
  30. visit2[id]=;
  31. dist[id]=distance;
  32. ;i<len;i++){
  33. son=map[id][i].v;
  34. if(!visit2[son]){
  35. LCA(son,distance+map[id][i].dis);
  36. aunion(id,son);
  37. }
  38.  
  39. }
  40. visit[id]=true;
  41. len=query[id].size();
  42. ;i<len;i++){
  43. son=query[id][i].v;
  44. if(visit[son]){
  45. ansque[query[id][i].dis]=dist[id]+dist[son]-*dist[father[getfather(son)]];
  46. //mark
  47. }
  48. }
  49. }
  50. int main(){
  51. while(scanf("%d%d",&n,&m)!=EOF){//attention
  52. //at the begining,we'd better to initialize all the vars
  53. int x,y,l;
  54. char a;
  55. node b;
  56. ;i<=n;i++){
  57. map[i].clear();//the mothod of the initialization of queue
  58. query[i].clear();
  59. father[i]=i;
  60. visit[i]=;
  61. visit2[i]=;
  62. ansque[i]=;
  63. dist[i]=;
  64. }
  65.  
  66. while(m--){
  67. scanf("%d %d %d %c",&x,&y,&l,&a);//only father
  68. b.v=y;b.dis=l;
  69. map[x].push_back(b);
  70. b.v=x;
  71. map[y].push_back(b);
  72. }
  73. scanf("%d",&m);
  74. node tmp2;
  75. ;i<m;i++){
  76. scanf("%d%d",&x,&y);
  77. tmp2.v=y;tmp2.dis=i;
  78. query[x].push_back(tmp2);
  79. tmp2.v=x;
  80. query[y].push_back(tmp2);
  81. }
  82. LCA(,);
  83. ;i<m;i++)
  84. printf("%d\n",ansque[i]);
  85. }
  86.  
  87. ;
  88. }

POJ1986 DistanceQueries 最近公共祖先LCA 离线算法Tarjan的更多相关文章

  1. LCA(最近公共祖先)离线算法Tarjan+并查集

    本文来自:http://www.cnblogs.com/Findxiaoxun/p/3428516.html 写得很好,一看就懂了. 在这里就复制了一份. LCA问题: 给出一棵有根树T,对于任意两个 ...

  2. 近期公共祖先(LCA)——离线Tarjan算法+并查集优化

    一. 离线Tarjan算法 LCA问题(lowest common ancestors):在一个有根树T中.两个节点和 e&sig=3136f1d5fcf75709d9ac882bd8cfe0 ...

  3. 最近公共祖先 LCA 倍增算法

          树上倍增求LCA LCA指的是最近公共祖先(Least Common Ancestors),如下图所示: 4和5的LCA就是2 那怎么求呢?最粗暴的方法就是先dfs一次,处理出每个点的深度 ...

  4. LCA离线算法Tarjan详解

    离线算法也就是需要先把所有查询给保存下来,最后一次输出结果. 离线算法是基于并查集实现的,首先就是初始化P[i] = i. 接下来对于每个点进行dfs: ①首先判断是否有与该点有关的查询,如果当前该点 ...

  5. LCA离线算法Tarjan的模板

    hdu 2586:题意:输入n个点的n-1条边的树,m组询问任意点 a b之间的最短距离 思路:LCA中的Tarjan算法,RMQ还不会.. #include <stdio.h> #inc ...

  6. 距离LCA离线算法Tarjan + dfs + 并查集

    距离B - Distance in the Tree 还是普通的LCA但是要求的是两个节点之间的距离,学到了一些 一开始我想用带权并查集进行优化,但是LCA合并的过程晚于离线计算的过程,所以路径长度会 ...

  7. HDU 2874 LCA离线算法 tarjan算法

    给出N个点,M条边.Q次询问 Q次询问每两点之间的最短距离 典型LCA 问题   Marjan算法解 #include "stdio.h" #include "strin ...

  8. LCA(最近公共祖先)——离线 Tarjan 算法

    tarjan算法的步骤是(当dfs到节点u时):1 在并查集中建立仅有u的集合,设置该集合的祖先为u1 对u的每个孩子v:   1.1 tarjan之   1.2 合并v到父节点u的集合,确保集合的祖 ...

  9. [模板] 最近公共祖先/lca

    简介 最近公共祖先 \(lca(a,b)\) 指的是a到根的路径和b到n的路径的深度最大的公共点. 定理. 以 \(r\) 为根的树上的路径 \((a,b) = (r,a) + (r,b) - 2 * ...

随机推荐

  1. 11g RAC R2 体系结构---用户及用户组

    10.2 RAC 到11.2 RAC 用户及用户组的变化: 在10.2 RAC 的部署中,只需要一个用户(oracle)和一个用户组(dba).Database.Clusterware都是用oracl ...

  2. 用“逐步排除”的方法定位Java服务线上“系统性”故障(转)

    一.摘要 由于硬件问题.系统资源紧缺或者程序本身的BUG,Java服务在线上不可避免地会出现一些“系统性”故障,比如:服务性能明显下降.部分(或所 有)接口超时或卡死等.其中部分故障隐藏颇深,对运维和 ...

  3. js执行上下文(由浅入深)

    每一个函数都有自己的执行上下文EC(执行环境 execution context),并且每个执行上下文中都有它自己的变量对象VO(Variable object),用于存储执行上下文中的变量 .函数声 ...

  4. 表达式语言之java对正则表达式的处理

    正则表达式用于字符串匹配,字符串查找,字符串替换等.例如注册email格式的验证等.java中处理正则表达式相关的类主要有java.lang.String,java.util.regex.Patter ...

  5. 【rest】 深入理解rest

    起因是想搞明白 ajax.rest风格和http请求数据会有什么区别 再来回顾一下概念: REST即表述性 状态 传递 满足这些约束条件和原则的应用程序或设计就是RESTful.需要注意的是,REST ...

  6. IOS键盘样式风格有关设置

    一.键盘风格 UIKit框架支持8种风格键盘. typedef  enum  { UIKeyboardTypeDefault,                 // 默认键盘:支持所有字符 UIKey ...

  7. 深入理解用mysql_fetch_row()以数组的形式返回查询结果

    同mysql_result()一样,mysql_fetch_row()也可以用来获取查询结果集,其区别在于函数的返回值不是一个字符串,而是一个数组.函数定义如下. 复制代码 代码如下: array m ...

  8. [SC] OpenSCManager FAILED 1722

    在服务器A(windows server 2008 r2)执行如下命令访问远端服务器B(windows server 2003)的服务运行状况: sc \\servername query " ...

  9. (转)使用 /proc 文件系统来访问 Linux 内核的内容

    转载网址:http://www.ibm.com/developerworks/cn/linux/l-proc.html 这个虚拟文件系统在内核空间和用户空间之间打开了一个通信窗口/proc 文件系统是 ...

  10. 自定义PopupWindow 怎么设置PopupWindow的宽度充满全屏宽度

    自定义了一个MyPopMenu类,用于上图中的下拉筛选效果的. 但是按照网上有说需要: new PopupWindow(view,getWindowManager().getDefaultDispla ...