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 bu 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 areato 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

LCA_倍增是LCA的在线算法,时间和空间复杂度分别是O((n+q)log n)和O(n log n)。
对于这个算法,我们从最暴力的算法开始:
①如果a和b深度不同,先把深度调浅,使他变得和浅的那个一样
②现在已经保证了a和b的深度一样,所以我们只要把两个一起一步一步往上移动,直到他们到达同一个节点,也就是他们的最近公共祖先了。

/*
author:gsw
data:2018.04.30
link:http://acm.hdu.edu.cn/showproblem.php?pid=2586
account:tonysave
*/
#define ll long long
#define IO ios::sync_with_stdio(false);
#define maxn 40005 #include<vector>
#include<math.h>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int t,n,m;
class Node{
public:
int nex,len;
};
vector<Node> tree[maxn];
int dis[maxn];int deep[maxn];
int fa[maxn]; void init()
{
for(int i=;i<n;i++)
tree[i].clear();
memset(dis,,sizeof(dis));
memset(deep,,sizeof(deep));
memset(fa,,sizeof(fa));
}
Node ne;
void dfs(int num,int faa)
{
for(int i=;i<tree[num].size();i++)
{
ne=tree[num][i];
if(ne.nex!=faa)
{
fa[ne.nex]=num;
deep[ne.nex]=deep[num]+;
dis[ne.nex]=dis[num]+ne.len;
dfs(ne.nex,num);
}
}
}
int lca(int a,int b)
{
if(deep[a]>deep[b])
swap(a,b);
while(deep[b]>deep[a])
b=fa[b];
while(a!=b)
a=fa[a],b=fa[b];
return a;
} int main()
{
int a,b,c;Node tem;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
init();
for(int i=;i<n-;i++)
{
scanf("%d%d%d",&a,&b,&c);
tem.nex=b;tem.len=c;
tree[a].push_back(tem);
tem.nex=a;
tree[b].push_back(tem);
}
dfs(,);
for(int i=;i<m;i++)
{
scanf("%d%d",&a,&b);
int ans=lca(a,b);
ans=dis[a]+dis[b]-*dis[ans];
printf("%d\n",ans);
}
}
}

HDU2586---How far away ?(lca算法)的更多相关文章

  1. LCA算法

    LCA算法: LCA(Least Common Ancestor),顾名思义,是指在一棵树中,距离两个点最近的两者的公共节点.也就是说,在两个点通往根的道路上,肯定会有公共的节点,我们就是要求找到公共 ...

  2. 【图论】tarjan的离线LCA算法

    百度百科 Definition&Solution 对于求树上\(u\)和\(v\)两点的LCA,使用在线倍增可以做到\(O(nlogn)\)的复杂度.在NOIP这种毒瘤卡常比赛中,为了代码的效 ...

  3. LCA算法解析-Tarjan&倍增&RMQ

    原文链接http://www.cnblogs.com/zhouzhendong/p/7256007.html UPD(2018-5-13) : 细节修改以及使用了Latex代码,公式更加美观.改的过程 ...

  4. LCA算法倍增算法(洛谷3379模板题)

    倍增(爬树)算法,刚刚学习的算法.对每一个点的父节点,就记录他的2k的父亲. 题目为http://www.luogu.org/problem/show?pid=3379 第一步先记录每一个节点的深度用 ...

  5. LCA 算法(二)倍增

     介绍一种解决最近公共祖先的在线算法,倍增,它是建立在任意整数的二进制拆分之上.   代码:   //LCA:Doubly #include<cstdio> #define swap(a, ...

  6. LCA 算法(一)ST表

    介绍一种解决最近公共祖先的在线算法,st表,它是建立在线性中的rmq问题之上.   代码:   //LCA: DFS+ST(RMQ) #include<cstdio> #include&l ...

  7. LCA算法总结

    LCA问题(Least Common Ancestors,最近公共祖先问题),是指给定一棵有根树T,给出若干个查询LCA(u, v)(通常查询数量较大),每次求树T中两个顶点u和v的最近公共祖先,即找 ...

  8. [算法整理]树上求LCA算法合集

    1#树上倍增 以前写的博客:http://www.cnblogs.com/yyf0309/p/5972701.html 预处理时间复杂度O(nlog2n),查询O(log2n),也不算难写. 2#st ...

  9. LCA算法笔记

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

  10. 对各种lca算法的理解

    1.RMQ+ST 首先注意这个算法的要素:结点编号,dfs序,结点深度. 首先dfs,求出dfs序,同时求出每个结点的深度.然后st算法,维护深度最小的结点编号(dfs序也可以,因为他们俩可以互相转换 ...

随机推荐

  1. 关于Burp Suite不能抓包的解决方法

    一.Burp Suite有时能抓到包,有时不能抓到包 解决方法: 出现这种问题的原因就是代理没有设置成全局的,只是设置成了局部的. 打开IE浏览器,依次打开工具->Internet 属性-> ...

  2. angularjs的select使用2

    https://cnodejs.org/topic/549007b44823a0234c9e1716 myAppModule.controller('FrmController', ['$scope' ...

  3. 筆記本 wifi走外网线 網卡走內網

    筆記本 wifi走外网线  網卡走內網 ,案列 -------------------------------------------------------- route print        ...

  4. Hive HiveQL基础知识及常用语句总结

    基础语句 CREATE DROP 建表.删表 建表 -------------------------------------- -- 1. 直接建表 ------------------------ ...

  5. 数据访问层的基类BaseDALSQL

    using System; using System.Text; using System.Collections; using System.Data; using System.Data.Comm ...

  6. Pandas数据处理 学习

    pandas是在numpy的基础上建立的新程序库,提供了一种高效的DataFrame数据结构. DataFrame本质上是一种带行标签和列标签.支持相同数据类型和缺失值的多维数组. 先看版本信息: p ...

  7. MHA+atlas(数据库的高可用与读写分离)

    学习完了mycat的高可用还是复习一下MHA+atlas吧,个人感觉还是比mycat好用,毕竟MHA有数据补全和切换主从的机制 1 MHA是什么? MHA(Master High Availabili ...

  8. Win7下VS2008安装cocos2d-2.0-x-2.0.4模板时, 运行InstallWizardForVS2008.js文件执行失败的解决办法

         今天在Win7环境下的VS2008中安装cocos2d-x模板的过程中,当点击InstallWizardForVS2008.js时,弹出" 没有文件扩展'.js'的脚本引擎&q ...

  9. python-并发编程之进程

    进程 python中创建进程模块为:multiprocessing 开销非常大 是计算机中资源分配的最小单位(内存隔离) 能利用多个CPU 由操作系统控制 同时操作内存之外的数据会产生数据的不安全 进 ...

  10. 第一节:mybatis入门

    1.新建数据表 本次测试使用mysql数据,数据库名称为mybatis,新建一张表person,建表语句如下: CREATE TABLE `person` ( `id` ) PRIMARY KEY a ...