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. laravel中文件上传:

    laravel5.5版本: congfig下的filesystems.php中配置:uploads信息: 'uploads' => [ 'driver' => 'local', 'root ...

  2. 网口扫盲二:Mac与Phy组成原理的简单分析

    1. general 下图是网口结构简图.网口由CPU.MAC和PHY三部分组成.DMA控制器通常属于CPU的一部分,用虚线放在这里是为了表示DMA控制器可能会参与到网口数据传输中. MAC(Medi ...

  3. Android 音视频深入 一 AudioRecord录音生成pcm转换为wav(附源码下载)

    本篇项目地址,名字是AudioRecord录音(能暂停,将pch转换为wav),求starhttps://github.com/979451341/Audio-and-video-learning-m ...

  4. day15-python常用内置模块的使用

    在日常的开发工作中,我们要写很多的python代码,如果都写在一个文件中,会导致代码特别难维护,为了拓展代码的可维护性,我们把函写在不同的文件里,这样每个文件包含的文件就比较少,逻辑更加清楚.在pyt ...

  5. Neo4J 教程

    好文转载: W3C: https://www.w3cschool.cn/neo4j/neo4j_cypher_api_example.html neo4j图数据库入门: http://blog.csd ...

  6. Mysql中contact、group_concat、concat_ws、repeat

    一.CONCAT(str1,str2,…) 返回结果为连接参数产生的字符串.如有任何一个参数为NULL ,则返回值为 NULL. mysql> select concat('11','22',' ...

  7. python安装与初始

    第一天学习中了解到python是高级语言,和java.PHP性质相同,而c语言.汇编属于低级语言,而高级语言与低级语言的区别,很重要的一点在于内存的处理上,低级语言在调用内存时需要自己编程来控制程序内 ...

  8. ssh免密登陆

    1:建立新用户hadoop 2:进入/home/hadoop/.ssh/目录 3:所有要免密连接的终端运行: ssh-keygen -t rsa 三次回车后会产生:id_rsa,id_rsa.pub两 ...

  9. day 29 socket 初级版

    # 客户端介绍简单版# import socket# #1买手机# phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #SOCK_STR ...

  10. javascript动态加载js文件主流浏览器兼容版

    一.代码示例: <html> <head> <meta http-equiv="Content-Type" content="text/ht ...