链接:

How far away ?

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

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
 
一个村子里有n个房子,这n个房子用n-1条路连接起来,接下了有m次询问,每次询问两个房子a,b之间的距离是多少。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <algorithm>
#include <set>
using namespace std;
typedef long long ll;
typedef unsigned long long Ull;
#define MM(a,b) memset(a,b,sizeof(a));
const double eps = 1e-;
const int inf =0x7f7f7f7f;
const double pi=acos(-);
const int maxn=; struct Edge{
int to,w;
Edge(int a,int b):to(a),w(b){};
Edge(){};
}e[maxn+]; struct node{
int to,id;
}; vector<Edge> G[maxn+];
vector<node> mp[maxn+];
int vis[maxn+],query[maxn+][],par[maxn+],dis[maxn+]; int findr(int u)
{
if(par[u]!=u)
par[u]=findr(par[u]);
return par[u];
} void unite(int u,int v)
{
int ru=findr(u);
int rv=findr(v);
if(ru!=rv) par[rv]=ru;
} void tarjan(int u,int val)
{
vis[u]=;
dis[u]=val; for(int i=;i<mp[u].size();i++)
{
int v=mp[u][i].to;
int id=mp[u][i].id;
if(vis[v])
query[id][]=findr(v);
} for(int i=;i<G[u].size();i++)
{
int v=G[u][i].to;
if(vis[v]) continue;
tarjan(v,val+G[u][i].w);
unite(u,v);
} } int main()
{
int cas,n,op,u,v,w;
scanf("%d",&cas);
while(cas--)
{
scanf("%d %d",&n,&op); for(int i=;i<=n;i++)
{
G[i].clear();
mp[i].clear();
vis[i]=;
par[i]=i;
} for(int i=;i<=n-;i++)
{
scanf("%d %d %d",&u,&v,&w);
G[u].push_back(Edge(v,w));
G[v].push_back(Edge(u,w));
} for(int i=;i<=op;i++)
{
scanf("%d %d",&u,&v);
query[i][]=u;
query[i][]=v;
mp[u].push_back((node){v,i});
mp[v].push_back((node){u,i});
} tarjan(,); for(int i=;i<=op;i++)
{
int u=query[i][];
int v=query[i][];
int r=query[i][];
printf("%d\n",dis[u]+dis[v]-*dis[r]);
}
}
return ;
}

分析:用的lca

1.因为有n-1条边,任意两点之间可达,那么就是一棵树;

2,假设当前是询问u和v两个点,他们的LCA是r,dis[]数组代表从根到点的距离,那么u和v两点之间的距离就是dis[u]+dis[v]-2*dis[r];所以只需要用Tarjan求一求询问的点对的LCA并且记录一下每个点到根(随便哪个点做根都可以)的距离就可以了

TTTTTTTTTTTTTTTTT HDU 2586 How far away LCA的离线算法 Tarjan的更多相关文章

  1. POJ 1470 Closest Common Ancestors (最近公共祖先LCA 的离线算法Tarjan)

    Tarjan算法的详细介绍,请戳: http://www.cnblogs.com/chenxiwenruo/p/3529533.html #include <iostream> #incl ...

  2. POJ1470Closest Common Ancestors 最近公共祖先LCA 的 离线算法 Tarjan

    该算法的详细解释请戳: http://www.cnblogs.com/Findxiaoxun/p/3428516.html #include<cstdio> #include<alg ...

  3. LCA(最近公共祖先)离线算法Tarjan+并查集

    本文来自:http://www.cnblogs.com/Findxiaoxun/p/3428516.html 写得很好,一看就懂了. 在这里就复制了一份. LCA问题: 给出一棵有根树T,对于任意两个 ...

  4. HDU 4547 CD操作 (LCA最近公共祖先Tarjan模版)

    CD操作 倍增法  https://i.cnblogs.com/EditPosts.aspx?postid=8605845 Time Limit : 10000/5000ms (Java/Other) ...

  5. HDU - 2586 How far away ?(离线Tarjan算法)

    1.给定一棵树,每条边都有一定的权值,q次询问,每次询问某两点间的距离. 2.这样就可以用LCA来解,首先找到u, v 两点的lca,然后计算一下距离值就可以了. 这里的计算方法是,记下根结点到任意一 ...

  6. HDU 2874 LCA离线算法 tarjan算法

    给出N个点,M条边.Q次询问 Q次询问每两点之间的最短距离 典型LCA 问题   Marjan算法解 #include "stdio.h" #include "strin ...

  7. LCA离线算法Tarjan的模板

    hdu 2586:题意:输入n个点的n-1条边的树,m组询问任意点 a b之间的最短距离 思路:LCA中的Tarjan算法,RMQ还不会.. #include <stdio.h> #inc ...

  8. LCA离线算法Tarjan详解

    离线算法也就是需要先把所有查询给保存下来,最后一次输出结果. 离线算法是基于并查集实现的,首先就是初始化P[i] = i. 接下来对于每个点进行dfs: ①首先判断是否有与该点有关的查询,如果当前该点 ...

  9. hdu 2586(最近公共祖先LCA)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 思路:在求解最近公共祖先的问题上,用到的是Tarjan的思想,从根结点开始形成一棵深搜树,非常好 ...

随机推荐

  1. Mac 如何将apache的这个默认目录更改到用户目录下

    如何将apache的这个默认目录更改到用户目录下. 做如下更改即可: 1.在自己的用户目录下新建一个Sites文件夹,我的用户目录为gaocuili 2.进到cd /etc/apache2/users ...

  2. 【6.28校内test】T3 【音乐会】道路千万条

    [音乐会]道路千万条[题目链接] 首先,你可以忽略上面的一大坨题面,只需要看说明的那一小部分就好啦. 然后理解题意: 就是说我们要给这n-1个运算符指定一个顺序,统计所有值为true的方案数pt,统计 ...

  3. C++笔记(0)——判定一个数字是否是素数

    博主之前使用的编程语言是Python,但是这门语言的效率比较低(通常,不优化的情况下,但是即便如此我还是偏爱Python),而且博主打算参加PAT考试(真正的原因),及博主打算顺便深入学习下机器学习框 ...

  4. AStar 启发函数设计(老物)

    作为我出山的第一篇日志,怎么也得写篇对得起我身份和地位的文章吧? 先容我吐槽一下不小心发的贴图,那个只是我不小心收藏了隔壁兄弟班的课表就别大家这么热情的 BB 我感到很有压力,额,废话不多说,立刻进入 ...

  5. java 导出自定义样式excel

    由于项目需要 要求导出一个这样的表格 然而 正常导出的表格都是这样婶儿地 这种格式网上demo有很多就不详细说了 ,主要说说上面三行是怎么画的. 第一行大标题,是9行合并成的一行,而且字体大小需要单独 ...

  6. TableView 两种Style Plain and Group 区别以及进阶使用

    一.UITableViewStylePlain 1.有多段时 段头停留(自带效果) 2.没有中间的间距和头部间距(要想有的重写UITableViewCell /UITableViewHeaderFoo ...

  7. Java 从后向前依次比较两个数组

    这是华为往年的一道上机题 题目: 给定两个数组,以及两个数组的长度,要求从最后一个元素开始,依次比较两个数组对应的元素.如果有一个数组较短,则以短数组为准.返回不同元素的个数. 解答: int fun ...

  8. 用 C++ 模板元编程实现有限的静态 introspection

    C++ 中的奇技淫巧大部分来源于模板技术,尤其是模版元编程技术(Template Meta-Programming, TMP).TMP 通过将一部分计算任务放在编译时完成,不仅提高了程序的性能,还能让 ...

  9. 使用Python的pandas-datareader包下载雅虎财经股价数据

    0 准备工作 首先,使用pip方法安装pandas和pandas-datareader两个功能包. 安装的方法十分简单,以管理员身份运行cmd. 输入以下命令. $ pip install panda ...

  10. [转载]一个支持Verilog的Vim插件——自动插入always块

    原文地址:一个支持Verilog的Vim插件--自动插入always块作者:hover 插件支持always块的自动插入,如果用户要插入时序always块,需要在端口声明中标志时钟和异步复位信号(仅支 ...