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. 【例子】log4j.properties例子讲解

    log4j.rootLogger=info, ServerDailyRollingFile, stdout log4j.appender.ServerDailyRollingFile=org.apac ...

  2. laravel中的登录页面逻辑

    <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades ...

  3. xml的方式配置AOP:Aspect Oriented Programming

    在某些类中, 什么时机, 做什么事情 切入点(point-cut): 在某些类中(Class<?>[] itfc = new Class<?>[] { IStudentServ ...

  4. Dom方法,解析XML文件

    Dom方法,解析XML文件的基本操作 package com.demo.xml.jaxp; import java.io.IOException; import javax.xml.parsers.D ...

  5. tfs 2017 使用

    安装完成之后,创建一个项目管理. 初始化代码库 然后下载代理 (服务器)并设置.下载代理需要FQ才可以下载成功. 想要支持 netcore2.0  必须在代理服务器上安装 vs2017 跟netcor ...

  6. SQL-14 从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t。 注意对于重复的emp_no进行忽略。

    题目描述 从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t.注意对于重复的emp_no进行忽略.CREATE TABLE IF NOT EXISTS &q ...

  7. Docker常用命令学习

    sudo service docker startsudo docker run hello-worlddocker stats --helpdocker run -d -P training/web ...

  8. Visual Studio Code用户设置文件

    打开 settings.json 文件 修改主题 修改工作区域背景色为豆绿色 { "workbench.colorTheme": "Visual Studio Light ...

  9. 在linux执行kettle

    1.下载 最新版下载 7.1 https://community.hitachivantara.com/docs/DOC-1009855 2.准备 3.上传任务文件 .kjb,.ktr 4.上传mys ...

  10. POJ - 1942 D - Paths on a Grid

    Imagine you are attending your math lesson at school. Once again, you are bored because your teacher ...