How far away ?

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

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
 
 
题目大意:
给你一棵树,求任两点的距离。
 
这是LCA模板题。
求出两点的公共祖先ancst,然后dis[i,j]=depth[i]+depth[j]-depth[ancst]*2;其中depth是节点在有根树中的深度。
离线tarjan算法。。ctrlc ctrlv一段大佬的解释吧。(来自zhouzhendong的cnblogs)
 

LCA_Tarjan

  TarjanTarjan 算法求 LCA 的时间复杂度为 O(n+q)O(n+q) ,是一种离线算法,要用到并查集。(注:这里的复杂度其实应该不是 O(n+q)O(n+q) ,还需要考虑并查集操作的复杂度 ,但是由于在多数情况下,路径压缩并查集的单次操作复杂度可以看做 O(1)O(1),所以写成了 O(n+q)O(n+q) 。)

  TarjanTarjan 算法基于 dfs ,在 dfs 的过程中,对于每个节点位置的询问做出相应的回答。

  dfs 的过程中,当一棵子树被搜索完成之后,就把他和他的父亲合并成同一集合;在搜索当前子树节点的询问时,如果该询问的另一个节点已经被访问过,那么该编号的询问是被标记了的,于是直接输出当前状态下,另一个节点所在的并查集的祖先;如果另一个节点还没有被访问过,那么就做下标记,继续 dfs 。

  当然,暂时还没那么容易弄懂,所以建议结合下面的例子和标算来看看。

(下面的集合合并都用并查集实现)

  比如:8−1−14−138−1−14−13 ,此时已经完成了对子树 11 的子树 1414 的 dfsdfs 与合并( 1414 子树的集合与 11 所代表的集合合并),如果存在询问 (13,14)(13,14) ,则其 LCA 即 getfather(14)getfather(14) ,即 11 ;如果还存在由节点 1313 与 已经完成搜索的子树中的 节点的询问,那么处理完。然后合并子树 1313 的集合与其父亲 11 当前的集合,回溯到子树 11 ,并深搜完所有 11 的其他未被搜索过的儿子,并完成子树 11 中所有节点的合并,再往上回溯,对节点 11 进行类似的操作即可。

 
大意就是,后根dfs一棵树,如果子树遍历完了,就把它整个加入子树根节点的父亲节点的并查集中。
遇到询问,就判断它的另一点是否已经遍历过了,如果是,就getfather。还是自己画画图,应该不难懂吧。
 
第一次写,比较粗糙,附AC代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <queue>
#include <deque>
#include <stack>
#include <map>
#include <set>
typedef long long LL;
const int MAX_N=;
const int MAX_M=;
const int INF=; struct tedge
{
int to,w,next;
};
tedge edge[MAX_N*+];
int head1[MAX_N+],cnt1; void addedge(int a,int b,int c)
{
edge[cnt1]=(tedge){b,c,head1[a]};head1[a]=cnt1++;
edge[cnt1]=(tedge){a,c,head1[b]};head1[b]=cnt1++;
} struct tquery
{
int to,next;
int index;
};
tquery query[MAX_M*+];
int head2[MAX_N+],cnt2; void addquery(int a,int b,int i)
{
query[cnt2]=(tquery){b,head2[a],i};head2[a]=cnt2++;
query[cnt2]=(tquery){a,head2[b],i};head2[b]=cnt2++;
} int fa[MAX_N]; int getf(int x)
{
if(fa[x]==x)
return x;
else
return fa[x]=getf(fa[x]);
} int vis[MAX_N+];
int depth[MAX_N+];
int ans[MAX_M+]; void LCA(int x,int pa,int dis)
{
for(int i=head1[x];i!=-;i=edge[i].next)
{
int l=edge[i].to;
if(l!=pa)
{
LCA(l,x,dis+edge[i].w);
}
}
depth[x]=dis;
for(int i=head2[x];i!=-;i=query[i].next)
{
int l=query[i].to;
if(vis[l])
{
int ancst=getf(l);
ans[query[i].index]=depth[l]+depth[x]-depth[ancst]*;
//printf("%d %d %d\n",l,x,ancst);
}
}
fa[x]=pa;vis[x]=;
} void init()
{
memset(head1,-,sizeof(head1));cnt1=;
memset(head2,-,sizeof(head2));cnt2=;
memset(vis,,sizeof(vis));
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
init();
int n,m;
scanf("%d%d",&n,&m);
for(int i=,a,b,c;i<=n-;i++)
{
scanf("%d%d%d",&a,&b,&c);
addedge(a,b,c);
}
for(int i=,a,b;i<=m;i++)
{
scanf("%d%d",&a,&b);
addquery(a,b,i);
}
for(int i=;i<=n;i++)
fa[i]=i;
LCA(,-,);
for(int i=;i<=m;i++)
printf("%d\n",ans[i]);
}
return ;
}

hdu 2586 How far away?(LCA模板题+离线tarjan算法)的更多相关文章

  1. hdu 3549 Flow Problem 最大流问题 (模板题)

    Flow Problem Time Limit: 5000/5000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Tota ...

  2. 近期公共祖先(LCA)——离线Tarjan算法+并查集优化

    一. 离线Tarjan算法 LCA问题(lowest common ancestors):在一个有根树T中.两个节点和 e&sig=3136f1d5fcf75709d9ac882bd8cfe0 ...

  3. HDU - 2586 How far away ?(LCA模板题)

    HDU - 2586 How far away ? Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & ...

  4. HDU 2586——How far away ?——————【LCA模板题】

    How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  5. HDU 2602 - Bone Collector - [01背包模板题]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2602 Many years ago , in Teddy’s hometown there was a ...

  6. HDU 2544 最短路 【Dijkstra模板题】

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=2544 思路:最短路的模板题 Dijkstra 算法是一种类似于贪心的算法,步骤如下: 1.当到一个点时, ...

  7. 【网络流#2】hdu 1533 - 最小费用最大流模板题

    最小费用最大流,即MCMF(Minimum Cost Maximum Flow)问题 嗯~第一次写费用流题... 这道就是费用流的模板题,找不到更裸的题了 建图:每个m(Man)作为源点,每个H(Ho ...

  8. hdu 1711 Number Sequence(KMP模板题)

    我的第一道KMP. 把两个数列分别当成KMP算法中的模式串和目标串,这道题就变成了一个KMP算法模板题. #include<stdio.h> #include<string.h> ...

  9. HDU 1874 畅通工程续(模板题——Floyd算法)

    题目: 某省自从实行了很多年的畅通工程计划后,终于修建了很多路.不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行走的距离要短很多.这让行人很困扰 ...

随机推荐

  1. Flutter学习笔记(30)--Android原生与Flutter混编

    如需转载,请注明出处:Flutter学习笔记(30)--Android原生与Flutter混编 这篇文章旨在学习如何在现有的Android原生项目上集成Flutter,实现Android与Flutte ...

  2. python3 之 内置函数range()

    一.语法: range(stop) range(start,stop,step) start:计数从start开始,默认是从0开始.eg:range(5)等价于range(0,5) stop:计数到s ...

  3. Spring与Redis整合(spring-data-redis)

    maven依赖 <properties> <!-- redis 版本 --> <redis.version>2.9.0</redis.version> ...

  4. Java正则表达式Pattern和Matcher类

    转载自--小鱼儿是坏蛋(原文链接) 概述 Pattern类的作用在于编译正则表达式后创建一个匹配模式.    Matcher类使用Pattern实例提供的模式信息对正则表达式进行匹配 Pattern类 ...

  5. Leetcode_01【两数之和】

    文章目录:  题目 脚本一及注释 脚本逻辑 脚本二及注释 脚本逻辑 题目: 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. ...

  6. desc和show

    desc只能查看表结构 查看zx1表结构 desc zx1; mysql> desc zx1 -> ; +---------+---------+------+-----+-------- ...

  7. MyEclispe启动Tomcat7时出现错误The servlets named [LoginServlet] and [com.liu.control.LoginServlet] are both

    刚开始尝试写Servlet代码,第一天就碰到这个错误,在网上找了很多资料才找到解决办法,在此记录一下. org.apache.catalina.LifecycleException: Failed t ...

  8. python读写配置文件使用总结与避坑指南

    关于今天的内容 最近拿python在写项目部署的相关集成代码,本来两天的工作量,硬是在来回的需求变更中,拖到了一周的时间.今天算是暂时告一段落了.这次由于涉及多个系统的调用和配置参数,代码开发中出现了 ...

  9. 基于webpack实现多html页面开发框架一 准备工作

    本系列主要介绍如何基于webpack实现多html页面开发框架,这里不讲webpack的基本概念,废话不多说,直奔主题! 前置条件: 1.安装node环境,自己去官网下载安装 2.新建文件夹webpa ...

  10. ActiveMQ配置策略

    1.消息发送 1.异步发送 消息生产者使用持久(persistent)传递模式发送消息的时候,Producer.send() 方法会被阻塞,直到 broker 发送一个确认消息给生产者,这个确认消息暗 ...