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
解题思路:Tarjan算法求树上任意两点的最短路。
AC代码:
 #include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=;
const int maxv=;
int T,n,m,x,y,z,fa[maxn],dist[maxn],ans[maxv];bool vis[maxn];
vector<pair<int,int> > tree[maxn],query[maxn];
void init(){
for(int i=;i<=n;++i)fa[i]=i,tree[i].clear(),query[i].clear();
memset(vis,false,sizeof(vis));
memset(dist,,sizeof(dist));
memset(ans,,sizeof(ans));
}
int query_father(int x){
int per=x,tmp;
while(fa[per]!=per)per=fa[per];
while(x!=per){tmp=fa[x];fa[x]=per;x=tmp;}//路径压缩
return x;
}
void unite(int x,int y){
x=query_father(x),y=query_father(y);
if(x!=y)fa[y]=x;
}
void Tarjan_LCA(int cur,int val){
vis[cur]=true;///先标记为true,这样如果同一支树上前面的祖先节点已访问,但是还没有归并到集合中去相当于为其本身,所以对下面计算两个节点的最近距离是没有影响的
dist[cur]=val;
for(size_t i=;i<tree[cur].size();++i){
int v=tree[cur][i].first;
int w=tree[cur][i].second;
if(!vis[v]){
Tarjan_LCA(v,val+w);///先序遍历
unite(cur,v);///回退后续遍历归并集合
}
}
for(size_t i=;i<query[cur].size();++i){///同时扫描与cur有关的点对查询
int to=query[cur][i].first;
int id=query[cur][i].second;
if(vis[to])ans[id]=dist[cur]+dist[to]-*dist[query_father(to)];
}
}
int main(){
while(~scanf("%d",&T)){
while(T--){
scanf("%d%d",&n,&m);
init();
for(int i=;i<n;++i){
scanf("%d%d%d",&x,&y,&z);
tree[x].push_back(make_pair(y,z));
tree[y].push_back(make_pair(x,z));
}
for(int i=;i<=m;++i){
scanf("%d%d",&x,&y);
query[x].push_back(make_pair(y,i));
query[y].push_back(make_pair(x,i));
}
Tarjan_LCA(,);
for(int i=;i<=m;++i)printf("%d\n",ans[i]);
}
}
return ;
}

LCA最近公共祖先知识点整理的更多相关文章

  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. LCA最近公共祖先 ST+RMQ在线算法

    对于一类题目,是一棵树或者森林,有多次查询,求2点间的距离,可以用LCA来解决.     这一类的问题有2中解决方法.第一种就是tarjan的离线算法,还有一中是基于ST算法的在线算法.复杂度都是O( ...

  8. Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)【转】【修改】

    一.基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成 ...

  9. (转)Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)

    基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成多个 ...

随机推荐

  1. String,StringBuilder与StringBuffer的区别

    相信大家看到过很多比较String和StringBuffer区别的文章,也明白这两者的区别,然而自从Java 5.0发布以后,我们的比较列表上将多出一个对象了,这就是StringBuilder类.St ...

  2. JVM的CPU资源占用过高问题的排查

    互联网后端架构 https://mp.weixin.qq.com/s/LiqAy2DikbmZzqogb5XRdA JVM的CPU资源占用过高问题的排查 互联网后端架构  今天 上午线上某应用的一台J ...

  3. 轮廓线DP:poj 2279 Mr. Young's Picture Permutations

    poj 2279 Mr. Young's Picture Permutations \(solution:\) 首先摘取一些关键词:(每行不超过它后面的行)(每排学生安排高度从左到右减少)(学生的高度 ...

  4. 创建Material Design风格的Android应用--应用主题

    本人全部文章首先公布于个人博客,欢迎关注,地址:http://blog.isming.me 昨天正式公布了android 5,同一时候android developer站点也更新了,添加了创建Mate ...

  5. MYSQL初级学习笔记一:MYSQL常用命令和数据库操作(DDL)!(视频序号:初级_3,4)

    知识点一:MYSQL常用命令(3) 登入方法:一,mysql –u 账号 –p 密码 退出方法:一,EXIT,QUIT 修改MYSQL命令提示符: 连接上客户机之后,通常使用prompt命令修改: 连 ...

  6. android:oneshot

    帧动画的自动执行:oneshot . 如果为true,表示动画只播放一次停止在最后一帧上,如果设置为false表示动画循环播放.

  7. Opencv:10个步骤检测出图片中条形码

    1. 原图像大小调整,提高运算效率 2. 转化为灰度图 3. 高斯平滑滤波 4.求得水平和垂直方向灰度图像的梯度差,使用Sobel算子 5.均值滤波,消除高频噪声 6.二值化 7.闭运算,填充条形码间 ...

  8. 多线程-threading模块3

    超级播放器 #coding:utf-8 import threading from time import sleep,ctime #超级播放器 def super_player(file,time) ...

  9. java try·····catch·····异常处理学习

    异常处理(又称为错误处理)功能 用于处理软件或信息系统中出现的异常状况(即超出程序正常执行流程的某些特殊条件). try....catch....只是异常处理的一种常用方法 try{ //可能导致异常 ...

  10. BZOJ1787 meet

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1787 水题,但是结论很有趣. 题目求的是距离三个点之和最小的点. 这个很显然是在三个LCA上, ...