题目链接

Problem Description
There are n houses in the village and some bidirectional roads connecting them. Every day peole always like to ask like this "How far is it if I want to go from house A to house B"? Usually it hard to answer. But luckily int this village the answer is always unique, since the roads are built in the way that there is a unique simple path("simple" means you can't visit a place twice) between every two houses. Yout task is to answer all these curious people.
 
Input
First line is a single integer T(T<=10), indicating the number of test cases.
  For each test case,in the first line there are two numbers n(2<=n<=40000) and m (1<=m<=200),the number of houses and the number of queries. The following n-1 lines each consisting three numbers i,j,k, separated by a single space, meaning that there is a road connecting house i and house j,with length k(0<k<=40000).The houses are labeled from 1 to n.
  Next m lines each has distinct integers i and j, you are to answer the distance between house i and house j.
 
Output
For each test case,output m lines. Each line represents the answer of the query. Output a bland line after each test case.
 
Sample Input
2
3 2
1 2 10
3 1 15
1 2
2 3
 
 
2 2
1 2 100
1 2
2 1
 
Sample Output
10
25
100
100

题意:有一棵有n个节点的树,每条边上有一个权值代表这两个点之间的距离,现在m次询问:从节点a到节点b的路径长?

思路:预处理所有节点到根节点(定为节点1)的距离,以及所有节点的祖先信息(fa[i][j]表示节点 i 向上距离为 (1<<j)的祖先节点编号),计算a和b到根节点的距离和,减去两倍的最近公共祖先的到根节点的距离值。

代码如下:

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <cstdio>
  4. #include <cstring>
  5. using namespace std;
  6. const int N = 4e4 + ;
  7.  
  8. int head[N], cnt;
  9. struct Edge
  10. {
  11. int to, next;
  12. int value;
  13. }e[ * N];
  14.  
  15. struct Node {
  16. int fa[];
  17. int deep;
  18. int sum;
  19. bool state;
  20. }node[N];
  21.  
  22. void insert(int u, int v, int value)
  23. {
  24. e[++cnt].to = v;
  25. e[cnt].next = head[u];
  26. e[cnt].value = value;
  27. head[u] = cnt;
  28. e[++cnt].to = u;
  29. e[cnt].next = head[v];
  30. e[cnt].value = value;
  31. head[v] = cnt;
  32. }
  33. int cal(int x, int t)
  34. {
  35. for (int i = ; i <= ; i++)
  36. if (t&( << i)) x = node[x].fa[i];
  37. return x;
  38. }
  39. void dfs(int x)
  40. {
  41. node[x].state = ;
  42. for (int i = ; i <= ; i++)
  43. {
  44. if (node[x].deep<( << i))break;
  45. node[x].fa[i] = node[node[x].fa[i - ]].fa[i-];///倍增处理祖先信息
  46. }
  47. for (int i = head[x]; i; i = e[i].next)
  48. {
  49. if (node[e[i].to].state) continue;
  50. node[e[i].to].deep = node[x].deep+ ;
  51. node[e[i].to].fa[] = x;
  52. node[e[i].to].sum = node[x].sum+e[i].value;
  53. dfs(e[i].to);
  54. }
  55. }
  56. int lca(int x, int y)///求lca
  57. {
  58. if (node[x].deep<node[y].deep) swap(x, y);
  59. x = cal(x, node[x].deep - node[y].deep);
  60. for (int i = ; i >= ; i--)
  61. if (node[x].fa[i] != node[y].fa[i])
  62. {
  63. x = node[x].fa[i];
  64. y = node[y].fa[i];
  65. }
  66. if (x == y)return x;
  67. else return node[x].fa[];
  68. }
  69.  
  70. void init()
  71. {
  72. cnt = ;
  73. memset(head, , sizeof(head));
  74. memset(node, , sizeof(node));
  75. }
  76.  
  77. int main()
  78. {
  79. int T; cin >> T;
  80. while (T--)
  81. {
  82. init();
  83. int n, m; cin >> n >> m;
  84. for (int i = ; i < n-; i++) {
  85. int x, y, v; scanf("%d%d%d",&x,&y,&v);
  86. insert(x,y,v);
  87. }
  88. dfs();
  89. for (int i = ; i < m; i++) {
  90. int x, y; scanf("%d%d",&x,&y);
  91. int pa = lca(x, y);
  92. int ans = node[x].sum - node[pa].sum + node[y].sum - node[pa].sum;
  93. cout << ans << endl;
  94. }
  95. }
  96. return ;
  97. }

LCA最近公共祖先-- HDU 2586的更多相关文章

  1. lca 最近公共祖先

    http://poj.org/problem?id=1330 #include<cstdio> #include<cstring> #include<algorithm& ...

  2. Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载)

    Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载) 转载自:http://hi.baidu.com/lydrainbowcat/blog/item/2 ...

  3. LCA(最近公共祖先)模板

    Tarjan版本 /* gyt Live up to every day */ #pragma comment(linker,"/STACK:1024000000,1024000000&qu ...

  4. CodeVs.1036 商务旅行 ( LCA 最近公共祖先 )

    CodeVs.1036 商务旅行 ( LCA 最近公共祖先 ) 题意分析 某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间. 假设有N个城镇,首都编号为1,商人从 ...

  5. LCA近期公共祖先

    LCA近期公共祖先 该分析转之:http://kmplayer.iteye.com/blog/604518 1,并查集+dfs 对整个树进行深度优先遍历.并在遍历的过程中不断地把一些眼下可能查询到的而 ...

  6. LCA 近期公共祖先 小结

    LCA 近期公共祖先 小结 以poj 1330为例.对LCA的3种经常使用的算法进行介绍,分别为 1. 离线tarjan 2. 基于倍增法的LCA 3. 基于RMQ的LCA 1. 离线tarjan / ...

  7. HDU 4547 CD操作 (LCA最近公共祖先Tarjan模版)

    CD操作 倍增法  https://i.cnblogs.com/EditPosts.aspx?postid=8605845 Time Limit : 10000/5000ms (Java/Other) ...

  8. D5 LCA 最近公共祖先

    第一题: POJ 1330 Nearest Common Ancestors POJ 1330 这个题可不是以1为根节点,不看题就会一直wa呀: 加一个找根节点的措施: #include<alg ...

  9. LCA 最近公共祖先 Tarjan(离线)算法的基本思路及其算法实现

    首先是最近公共祖先的概念(什么是最近公共祖先?): 在一棵没有环的树上,每个节点肯定有其父亲节点和祖先节点,而最近公共祖先,就是两个节点在这棵树上深度最大的公共的祖先节点. 换句话说,就是两个点在这棵 ...

随机推荐

  1. node.js中pm2启动应用出错

    在将公司的应用容器化时,遇到的问题. 之前,同事使用node.js 6版本运行,pm2启动js文件,一切正常. 但我一样将node.js 6版本安装,然后npm install pm2完成. 运行pm ...

  2. background-origin和background-origin和2D转换

    1--> background-origin:可以定义背景图片的定位区域,它有3个属性值 background-origin:border-box /padding-box/ content-b ...

  3. 爬虫 crawlSpider 分布式 增量式 提高效率

    crawlSpider 作用:为了方便提取页面整个链接url,不必使用创参寻找url,通过拉链提取器,将start_urls的全部符合规则的URL地址全部取出 使用:创建文件scrapy startp ...

  4. VLAN实验(5)三层交换

    1.选择1台S5700和3台pc机,并根据实验编址完成此拓扑图. 2.检查连通性 (1)因为mengyu-PC1和mengyu-PC2在一个地址段上,可以ping通 (2)因为mengyu-PC1和m ...

  5. KPConv针对Modelnet40的分类

    1. 训练样本airplane_0001.txt的可视化: 飞机尺度: 物体类别与对应标签: 2. 对训练样本进行降采样: 体素法降采样,降采样的网络大小设置为0.02m.在pycharm下面的Con ...

  6. C读取json格式字符串

    python调用C库时参数太多,约定传json格式字符串,C解析 #include<stdio.h> #include<string.h> #include<stdlib ...

  7. JAVA基础系列:ThreadLocal

    1. 思路 什么是ThreadLocal?ThreadLocal类顾名思义可以理解为线程本地变量.也就是说如果定义了一个ThreadLocal,每个线程往这个ThreadLocal中读写是线程隔离,互 ...

  8. (二十八)golang--二维数组

    初始化: var array [2][3]int = [2][3]int{{0,0,0},{0,0,0}} var array [2][3]int = [...][3]int{{0,0,0},{0,0 ...

  9. PHP匿名函数的写法

    传统写法<pre>function timer () { echo "hello world";}Swoole\Timer::tick(2000, 'timer');& ...

  10. vue项目使用Ueditor富文本编辑器总结

    我使用的是前端大佬封装的vue-ueditor-wrap插件,结合ueditor本身的压缩包开发的. 1.下载vue-ueditor-wrap: npm install vue-ueditor-wra ...