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 ;
}

最新文章

  1. windows平台eclipse for C++开发环境搭建
  2. java8中CAS的增强
  3. 与你相遇好幸运,The Moe Node.js Code Style Guide
  4. js:方法3. 对象
  5. js替换字符串中全部“-”
  6. 菜鸟互啄:WINFORM如何实现无聚焦框的Button按钮
  7. android应用开发小技巧
  8. wordpress怎么禁止文章复制
  9. 在Windows上使用Let加密IIS
  10. Ubuntu 16.04.3 LTS u盘-安裝教程(填坑)
  11. H5唤醒app,第三方开源库
  12. 洛谷P1135 奇怪的电梯【bfs】
  13. shadow一键安装
  14. sublime中如何用less实现css预编译
  15. echarts折线图个性化填充、线条、拐点样式
  16. Netty源码分析第2章(NioEventLoop)----&gt;第6节: 执行select操作
  17. Android-获取手机已经安装的程序
  18. leetcode547
  19. adb的常用命令及如何查看被占用的端口
  20. 深入理解javascript原型和闭包_____全部

热门文章

  1. 【配置关系】—Entity Framework实例详解
  2. dubbo简单配置与使用
  3. 使用TASM编译COFF格式和连接
  4. Netty实现时间服务演示样例
  5. 处理TCP连包的一小段代码
  6. hihoCoder 1584 Bounce 【数学规律】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛)
  7. Vijos P1389婚礼上的小杉
  8. oracle监听器启动,实例启动
  9. CodeForces-607B:Zuma (基础区间DP)
  10. 使用pngcrush压缩png图片