Distance Queries
Time Limit: 2000MS   Memory Limit: 30000K
Total Submissions: 11304   Accepted: 3985
Case Time Limit: 1000MS

Description

Farmer John's cows refused to run in his marathon since he chose a path much too long for their leisurely lifestyle. He therefore wants to find a path of a more reasonable length. The input to this problem consists of the same input as in "Navigation Nightmare",followed by a line containing a single integer K, followed by K "distance queries". Each distance query is a line of input containing two integers, giving the numbers of two farms between which FJ is interested in computing distance (measured in the length of the roads along the path between the two farms). Please answer FJ's distance queries as quickly as possible! 

Input

* Lines 1..1+M: Same format as "Navigation Nightmare"

* Line 2+M: A single integer, K. 1 <= K <= 10,000

* Lines 3+M..2+M+K: Each line corresponds to a distance query and contains the indices of two farms.

Output

* Lines 1..K: For each distance query, output on a single line an integer giving the appropriate distance. 

Sample Input

7 6
1 6 13 E
6 3 9 E
3 5 7 S
4 1 3 N
2 4 20 W
4 7 2 S
3
1 6
1 4
2 6

Sample Output

13
3
36
学习LCA的好文章:http://taop.marchtea.com/04.04.html
离线:将所有查询输入完毕后再统一输出结果。
在线:查询一个输出一个。 dfs+并查集,离线
#include <cstdio>
#include <vector>
using namespace std;
const int MAXN=;
int n,m,k;
struct Edge{
int to,w;
Edge(){}
Edge(int to,int w)
{
this->to=to;
this->w=w;
}
};
vector<Edge> arc[MAXN]; struct Node{
int to,id;
Node(){}
Node(int to,int id)
{
this->to=to;
this->id=id;
}
};
vector<Node> que[MAXN]; int par[MAXN];
void prep()
{
for(int i=;i<MAXN;i++)
{
d[i]=;
vis[i]=;
par[i]=i;
}
}
int fnd(int x)
{
if(par[x]==x)
{
return x;
}
return par[x]=fnd(par[x]);
}
void unite(int fa,int son)
{
int a=fnd(fa);
int b=fnd(son);
par[b]=a;
} int vis[MAXN],d[MAXN];
int res[MAXN];
void tarjan(int u)
{
vis[u]=;
for(int i=,size=que[u].size();i<size;i++)
{
Node nod=que[u][i];
if(vis[nod.to])
{
int lca=fnd(nod.to);
res[nod.id]=d[nod.to]+d[u]-*d[lca];
}
}
for(int i=,size=arc[u].size();i<size;i++)
{
Edge e=arc[u][i];
if(!vis[e.to])
{
d[e.to]=d[u]+e.w;
tarjan(e.to);
unite(u,e.to);
}
}
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
prep();
for(int i=;i<=n;i++) arc[i].clear();
for(int i=;i<m;i++)
{
int u,v,w;
scanf("%d %d %d %*c",&u,&v,&w);
arc[u].push_back(Edge(v,w));
arc[v].push_back(Edge(u,w));
}
scanf("%d",&k);
for(int i=;i<k;i++)
{
int u,v;
scanf("%d%d",&u,&v);
que[v].push_back(Node(u,i));
que[u].push_back(Node(v,i));
}
for(int i=;i<=n;i++)
{
if(!vis[i])
{
tarjan(i);
}
}
for(int i=;i<k;i++)
{
printf("%d\n",res[i]);
}
}
return ;
}
模板:RMQ求LCA在线算法(稀疏表实现RMQ)
#include <cstdio>
#include <cstring>
#include <vector>
#include <math.h>
#include <algorithm>
using namespace std;
const int MAXN=;
int n,m,k;
struct Edge{
int to,w;
Edge(){}
Edge(int to,int w)
{
this->to=to;
this->w=w;
}
};
vector<Edge> arc[MAXN]; int vs[MAXN+MAXN],depth[MAXN+MAXN],first[MAXN],tot;
int d[MAXN],vis[MAXN];
void dfs(int u,int dep)
{
vis[u]=;
vs[++tot]=u;
depth[tot]=dep;
first[u]=tot;
for(int i=,size=arc[u].size();i<size;i++)
{
Edge e=arc[u][i];
if(!vis[e.to])
{
d[e.to]=d[u]+e.w;
dfs(e.to,dep+);
vs[++tot]=u;
depth[tot]=dep;
}
}
} int dp[MAXN+MAXN][];
void init_st(int size)
{
for(int i=;i<=size;i++) dp[i][]=i;
for(int j=;j<;j++)
{
for(int i=;i<=size;i++)
{
if(i+(<<j)-<=size)
{
int a=dp[i][j-];
int b=dp[i+(<<(j-))][j-];
dp[i][j]=depth[a]<depth[b]?a:b;
}
}
}
}
int rmq_st(int l,int r)
{
int limit=(int)(log(r-l+1.0)/(log(2.0)));
int a=dp[l][limit];
int b=dp[r-(<<limit)+][limit];
return depth[a]<depth[b]?a:b;
} int LCA(int u,int v)
{
if(first[u]>first[v]) swap(u,v);
int id=rmq_st(first[u],first[v]);
return vs[id];
} int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
tot=;
memset(vis,,sizeof(vis));
memset(d,,sizeof(d));
for(int i=;i<=n;i++) arc[i].clear();
for(int i=;i<m;i++)
{
int u,v,w;
scanf("%d %d %d %*c",&u,&v,&w);
arc[u].push_back(Edge(v,w));
arc[v].push_back(Edge(u,w));
}
for(int i=;i<=n;i++)
{
if(!vis[i])
{
dfs(i,);
}
}
init_st(tot);
scanf("%d",&k);
for(int i=;i<k;i++)
{
int u,v;
scanf("%d%d",&u,&v);
int lca=LCA(u,v);
int res=d[u]+d[v]-*d[lca];
printf("%d\n",res);
}
}
return ;
}
												

POJ1986(LCA应用:求两结点之间距离)的更多相关文章

  1. hdoj 1869 六度分离【最短路径求两两边之间最长边】

    六度分离 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  2. 求两个数之间的质数 -----------基于for循环 算法思想

    前端代码: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.as ...

  3. js求连个数之间的数字

    整理出自项目中一个需求,求两个数之间的数字. const week = function(arr,arr2){ let a=parseInt(arr); let b=parseInt(arr2); l ...

  4. 「POJ-3608」Bridge Across Islands (旋转卡壳--求两凸包距离)

    题目链接 POJ-3608 Bridge Across Islands 题意 依次按逆时针方向给出凸包,在两个凸包小岛之间造桥,求最小距离. 题解 旋转卡壳的应用之一:求两凸包的最近距离. 找到凸包 ...

  5. 求两点之间距离 C++

    求两点之间距离(20 分) 定义一个Point类,有两个数据成员:x和y, 分别代表x坐标和y坐标,并有若干成员函数. 定义一个函数Distance(), 用于求两点之间的距离.输入格式: 输入有两行 ...

  6. 旋转卡壳求两个凸包最近距离poj3608

    #include <iostream> #include <cmath> #include <vector> #include <string.h> # ...

  7. JavaScript求两个数字之间所有数字的和

    这是在fcc上的中级算法中的第一题,拉出来的原因并不是因为有什么好说的,而是我刚看时以为是求两个数字的和, 很显然错了.我感觉自己的文字理解能力被严重鄙视了- -.故拉出来折腾折腾. 要求: 给你一个 ...

  8. GPS(2)关于位置的3个示例,实时获取GPS定位数据,求两个经纬点距离,邻近某个区域圆时警告

    实时获取GPS定位数据 import android.app.Activity; import android.content.Context; import android.location.Loc ...

  9. js 求两个日期之间相差天数

    //求两个日期之间的相差天数 function daysBetween(DateOne, DateTwo) { var OneMonth = DateOne.substring(5, DateOne. ...

随机推荐

  1. 全命令行手写MapReduce并且打包运行

    主要要讲的有3个 java中的package是干啥的? 工作了好几年的都一定真正理解java里面的package关键字,这里在写MapReduce需要进行打包的时候突然发现命令行下打包运行居然不会了, ...

  2. 基于IAP和网口升级固件

    基于IAP和网口升级固件 一.      需求引入 现有嵌入式设备:基于ARM Cortex-M3处理器.带以太网通讯功能. 为减少设备维护成本节省宝贵的时间和金钱,须要设计网口升级固件功能. 本文描 ...

  3. 【WPF学习笔记】之 System.Exception 对象名 'XXXX' 无效。

    我在运行vs时候发现项目报错,如下图: 报Exception错误,对象名“XXXXXX”无效. 经过调查得知,因为连接数据库的库名写错了,如下: 对应正确数据库的库名: 把库名改正确,问题就解决了.

  4. erlang中判断进程是否存活

    一个参数的方法是已知Pid判断进程是否存活.两个参数的方法是已知节点和Pid或进程名判断进程是否存活. is_process_alive(Pid) when is_pid(Pid)->rpc:c ...

  5. Android—— 4.2 Vold挂载管理_NetlinkManager (四)

    在前文Android-- 4.2 Vold挂载管理_主体构建main (一)中有结构图表示,Vold是kernel与用户层的一个交互管理模块. Android-- 4.2 Vold挂载管理_Volum ...

  6. 【BZOJ2597】[Wc2007]剪刀石头布 最小费用流

    [BZOJ2597][Wc2007]剪刀石头布 Description 在一些一对一游戏的比赛(如下棋.乒乓球和羽毛球的单打)中,我们经常会遇到A胜过B,B胜过C而C又胜过A的有趣情况,不妨形象的称之 ...

  7. Swift 学习笔记(扩展和泛型)

    在开始介绍Swift中的扩展之前,我们先来回忆一下OC中的扩展. 在OC中如果我们想对一个类进行功能的扩充,我们会怎么做呢. 对于面向对象编程的话,首先会想到继承,但是继承有两个问题. 第一个问题:继 ...

  8. Python爬虫-- BeautifulSoup库

    BeautifulSoup库 beautifulsoup就是一个非常强大的工具,爬虫利器.一个灵活又方便的网页解析库,处理高效,支持多种解析器.利用它就不用编写正则表达式也能方便的实现网页信息的抓取 ...

  9. 【学习笔记】快速傅里叶变换(FFT)

    [学习笔记]快速傅里叶变换 学习之前先看懂这个 浅谈范德蒙德(Vandermonde)方阵的逆矩阵的求法以及快速傅里叶变换(FFT)中IDFT的原理--gzy hhh开个玩笑. 讲一下\(FFT\) ...

  10. Dijkstra的堆优化

    先附上一个例题:P3371 [模板]单源最短路径 一眼扫去,最短路... spfa可行,但是今天的主题是Dijkstra: #include<iostream> #include<a ...