http://acm.hdu.edu.cn/showproblem.php?pid=2586

How far away ?

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 21250    Accepted Submission(s): 8368

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
题目大意:给一个有权树,有Q次询问,求任意两点的距离。
题目分析:在树中有一个性质:任意两点的距离 ANS = dist[ u ] + dist[ v ] - dist[ lca(u,v)  ],其中dist[ I ]是根到 I 的 距离 ,由于需要多次询问,所以使用Tarjan离线求LCA比较快
 #include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
const int maxn=;
struct edge{
int to;
int len;
};
vector<struct edge>G[maxn];
vector<int>qury[maxn];
vector<int>num[maxn];
int dis[maxn],vis[maxn],ans[maxn],fa[maxn];
void init()
{
memset(dis,,sizeof(dis));
memset(vis,,sizeof(vis));
for(int i = ; i < ; i++)
{
G[i].clear();
qury[i].clear();
num[i].clear();
fa[i]=i;
}
}
int find(int x)
{
int xx=x;
while(fa[x]!=x)
{
x=fa[x];
}
while(fa[xx]!=x)
{
int t=fa[xx];
fa[xx]=x;
xx=t;
}
return x;
}
void Union(int x,int y)
{
int xx=find(x);
int yy=find(y);
if(xx!=yy);
fa[yy]=xx;//在完成子节点的Tarjan遍历之后,把子节点纳入父节点名下
}
void Tarjan(int u,int ll)
{
vis[u]=;
dis[u]=ll;
for(int i = ; i< G[u].size() ;i++)
{
struct edge wqw=G[u][i];
if(vis[wqw.to])continue;
Tarjan(wqw.to,wqw.len+ll);
Union(u,wqw.to);
}
for(int i = ; i < qury[u].size() ; i++)
{
if(vis[qury[u][i]])
{
ans[num[u][i]]=dis[u]+dis[qury[u][i]]-*dis[find(qury[u][i])];
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
init();
int n,m;
scanf("%d%d",&n,&m);
for(int i = ; i < n ; i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
G[a].push_back((struct edge){b,c});
G[b].push_back((struct edge){a,c});
}
for(int i = ; i < m ; i++)
{
int a,b;
scanf("%d%d",&a,&b);
qury[a].push_back(b);
qury[b].push_back(a);
num[a].push_back(i);
num[b].push_back(i);
}
Tarjan(,);
for(int i = ; i < m ; i++)
{
printf("%d\n",ans[i]);
}
}
return ;
}

【HDOJ2586】【Tarjan离线求LCA】的更多相关文章

  1. tarjan算法求LCA

    tarjan算法求LCA LCA(Least Common Ancestors)的意思是最近公共祖先,即在一棵树中,找出两节点最近的公共祖先. 这里我们使用tarjan算法离线算法解决这个问题. 离线 ...

  2. Tarjan算法离线 求 LCA(最近公共祖先)

    本文是网络资料整理或部分转载或部分原创,参考文章如下: https://www.cnblogs.com/JVxie/p/4854719.html http://blog.csdn.net/ywcpig ...

  3. Tarjan 算法求 LCA / Tarjan 算法求强连通分量

    [时光蒸汽喵带你做专题]最近公共祖先 LCA (Lowest Common Ancestors)_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili tarjan LCA - YouTube Tarj ...

  4. HDU 2586 /// tarjan离线求树上两点的LCA

    题目大意: 询问一棵树里 u 到 v 的距离 可由 dis[ u到根 ] + dis[ v到根 ] - 2*dis[ lca(u,v) ] 得到 https://blog.csdn.net/csyzc ...

  5. POJ 1470 Closest Common Ancestors (模板题)(Tarjan离线)【LCA】

    <题目链接> 题目大意:给你一棵树,然后进行q次询问,然后要你统计这q次询问中指定的两个节点最近公共祖先出现的次数. 解题分析:LCA模板题,下面用的是离线Tarjan来解决.并且为了代码 ...

  6. HDU 2586 How far away ?(经典)(RMQ + 在线ST+ Tarjan离线) 【LCA】

    <题目链接> 题目大意:给你一棵带有边权的树,然后进行q次查询,每次查询输出指定两个节点之间的距离. 解题分析:本题有多重解决方法,首先,可用最短路轻易求解.若只用LCA解决本题,也有三种 ...

  7. HDU 2874 /// tarjan离线求森林里两点的距离

    题目大意: 在一个森林里 询问 u v 两点 若不能到达输出 "Not connected" 否则输出两点距离 https://blog.csdn.net/keyboarderqq ...

  8. Tarjan 离线算法LCA

    #include<map> #include<set> #include<cmath> #include<queue> #include<cstd ...

  9. SPOJ 10628 Count on a tree(Tarjan离线LCA+主席树求树上第K小)

    COT - Count on a tree #tree You are given a tree with N nodes.The tree nodes are numbered from 1 to  ...

随机推荐

  1. MATLAB图片折腾3

    把视频抽帧,转化成图片 我的代码如下,成功实现clc;clear;videofilename='k:\GraduationWork\Resource\video.wmv'; %where you pu ...

  2. Android : iperf-2.0.4 网络测试工具

    一.源码下载及交叉编译: 下载:https://pan.baidu.com/s/1i6NYDF3   //包含linux和windows上的可执行文件 1. 解压后获得perf-2.0.4源码.2. ...

  3. 关于netcore 发布到服务器的准备

    1.先cmd到指定的网站目录, 然后执行 dotnet xxx.dll, 浏览器查看 localhost:5000 确认没有问题之后才去部署到iis

  4. confirm消息对话框

    function rec(){ var mymessage= confirm("你是女孩?") ; if(mymessage==true) { document.write(&qu ...

  5. matlab中文本文件与图像转化

    一  将图片转化为txt文本文件 a=imread('picture.bmp');   //读取picture.bmp图片 b=rgb2gray(a);                 //由rgb图 ...

  6. Log4j 日志记录

    关于Log4j的简单示例 <!--手动配置log4j.properties文件内容:-->1 #level:debug/info/warn/error log4j.rootLogger=O ...

  7. EF6增改删等常用基类

    using System; using System.Linq; using System.Threading.Tasks; using System.Linq.Expressions; using ...

  8. <Flume><Source Code><Flume源码阅读笔记>

    Overview source采集的日志首先会传入ChannelProcessor, 在其内首先会通过Interceptors进行过滤加工,然后通过ChannelSelector选择channel. ...

  9. Linux下Ganglia集群监控安装、配置笔记

    http://www.blogjava.net/henry14/archive/2011/12/17/ganglia.html 枪声依旧 Linux下Ganglia集群监控安装.配置笔记 Gangli ...

  10. 使用Maven+ssm框架搭建一个web项目

    1,前期准备:Eclipse(Mars.2 Release (4.5.2)).jdk1.7.tomcat7.maven3.2.1 2.使用eclipse中的maven新建一个web项目 点击next: ...