题目链接acm.hdu.edu.cn/showproblem.php?pid=2586

题目大意:有n个点,同n-1条带有权值的双向边相连,有m个询问,每个询问包含两个数x,y,求x与y的最短距离。

例:

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-1条边,我们可以把它看成一颗树,然后我们把1号节点看成这颗树的根节点,这样我们计算任意两个点x,y的最短距离就可以简单表示为dis[x]+dis[y]-2*dis[lca(x,y)](其中dis[i]表示节点i到根节点的距离,lca(x,y)表示x,y的最近公共祖先)。
如果不会Tarjan离线算法可以看这个博客,http://www.cnblogs.com/JVxie/p/4854719.html,非常简单易懂。
直接用Tarjan离线算法模板便可求出答案。
 
附上代码:
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
#define maxn 400005
struct node{
int x,y;
};
vector<node> edge[maxn],que[maxn];
int ans[maxn],dis[maxn],par[maxn],vis[maxn];
//ans[i]表示第i次询问的答案,dis[i]表示i号节点与根节点的距离
//par[i]表示i号节点的父亲节点
int n,m; void init()
{
for(int i=;i<=n;i++)
{
edge[i].clear();
que[i].clear();
par[i]=i;
ans[i]=;
dis[i]=;
vis[i]=;
}
}
int find(int x)
{
if(x==par[x])
return x;
else
return par[x]=find(par[x]);
}
void unite(int x,int y)
{
int fatherx=find(x),fathery=find(y);
if(fatherx!=fathery)
par[fathery]=fatherx;
}
void TarjanLCA(int x)
{
vis[x]=;
for(int i=;i<edge[x].size();i++)
{
int v=edge[x][i].x;
if(!vis[v])
{
dis[v]=dis[x]+edge[x][i].y;
TarjanLCA(v);
unite(x,v);
}
}
for(int i=;i<que[x].size();i++)
{
int v=que[x][i].x;
if(vis[v])
ans[que[x][i].y]=dis[x]+dis[v]-*dis[find(v)];
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
init();
for(int i=;i<n;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
edge[u].push_back({v,w});
edge[v].push_back({u,w});
}
for(int i=;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
que[x].push_back({y,i});//i表示第几次询问,便于输出
que[y].push_back({x,i});
}
TarjanLCA();
for(int i=;i<=m;i++)
printf("%d\n",ans[i]);
}
return ;
}

hdu2586How far away ?(LCA LCATarjan离线)的更多相关文章

  1. HDU-2586-How far away(LCA Tarjan离线算法)

    链接:https://vjudge.net/problem/HDU-2586 题意: 勇气小镇是一个有着n个房屋的小镇,为什么把它叫做勇气小镇呢,这个故事就要从勇气小镇成立的那天说起了,修建小镇的时候 ...

  2. poj 1986 Distance Queries(LCA:倍增/离线)

    计算树上的路径长度.input要去查poj 1984. 任意建一棵树,利用树形结构,将问题转化为u,v,lca(u,v)三个点到根的距离.输出d[u]+d[v]-2*d[lca(u,v)]. 倍增求解 ...

  3. bzoj 3626 [LNOI2014]LCA(离线处理+树链剖分,线段树)

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1272  Solved: 451[Submit][Status ...

  4. poj 1330 LCA (倍增+离线Tarjan)

    /* 先来个倍增 */ #include<iostream> #include<cstring> #include<cstdio> #define maxn 100 ...

  5. POJ 1470 Closest Common Ancestors (LCA,离线Tarjan算法)

    Closest Common Ancestors Time Limit: 2000MS   Memory Limit: 10000K Total Submissions: 13372   Accept ...

  6. 最近公共祖先LCA Tarjan 离线算法

    [简介] 解决LCA问题的Tarjan算法利用并查集在一次DFS(深度优先遍历)中完成所有询问.换句话说,要所有询问都读入后才开始计算,所以是一种离线的算法. [原理] 先来看这样一个性质:当两个节点 ...

  7. POJ1470 LCA (Targan离线)

    bryce1010模板 http://poj.org/problem?id=1470 /*伪代码 Tarjan(u)//marge和find为并查集合并函数和查找函数 { for each(u,v) ...

  8. LCA的离线快速求法

    最常见的LCA(树上公共祖先)都是在线算法,往往带了一个log.有一种办法是转化为"+-1最值问题"得到O(n)+O(1)的复杂度,但是原理复杂,常数大.今天介绍一种允许离线时接近 ...

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

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

随机推荐

  1. Chrome浏览器的版本查看 以及V8 javascript 引擎版本查看

    1. 发现chrome浏览器最新版本里面带的V8 引擎 版本号与chrome的版本号有一个关系, 这里简单总结一下: 在地址栏里面输入: chrome://version 即可显示出来 比如我正在使用 ...

  2. [转帖]dd命令详解

    dd命令详解 https://czmmiao.iteye.com/blog/1748748 之前一直对linux的命令很恐惧 现在发现 其实不是那么复杂 要仔细学习就可以了 比如 dd = disk ...

  3. 《Effective C++》设计与声明:条款18-条款25

    条款18:让接口容易被正确使用,不容易被误用 注意使用const,explicit,shared_ptr等来限制接口. 必要时可以创建一些新的类型,限制类型操作,束缚对象等. 注意保持接口的一致性,且 ...

  4. 本地上传项目到github

    https://www.cnblogs.com/rosej/p/6056467.html(copy)

  5. github 操作

    https://www.cnblogs.com/cxk1995/p/5800196.html 1在已有的GitHub账号下创建项目. 2将GitHub项目克隆到本地.  git clone https ...

  6. Linux 的相关操作

    切换权限   在linux环境下,用户之前的切换使用 “su - name,若要切换到root下面,则使用sudo su 命令即可. 在linux下安装软件,经常就是装完后不知道装到哪里去了 (201 ...

  7. Django--CRM--一级, 二级 菜单表

    一. 一级菜单表 1. 首先要修改权限表的字段, 在权限表下面加上icon和 is_menu 的字段 2. 展示结果 # 我们既然想要动态生成一级菜单,那么就需要从数据库中拿出当前登录的用户的菜单表是 ...

  8. EmpireCMS的使用

    1.下载安装empirecms 下载完成后解压将upload目录整体上传到服务器,并更名为empirecms_test 更改目录文件的权限: chmod -R 777 empirecms_test 配 ...

  9. 一、hadoop部署

    一.Java环境 yum 安装方式安装 1.搜索JDK安装包 yum search java|grep jdk 2.安装 yum install java-1.8.0-openjdk-src.x86_ ...

  10. Lodop控件NewPage();测试输出空白页

    LODOP.NewPage();和LODOP.NewPageA();是强制分页语句,两者的区别可查看本博客的相关博文:Lodop强制分页LODOP.NewPage()和LODOP.NewPageA() ...