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. CentOS下安装python3.x版本

    现在python都到了3.x版本,但是centos中自带的python仍然是2.7版本的,所以想把python换成3.x版本的. 但是这个地方有个坑,你要是直接编译安装了python3.x之后,估计你 ...

  2. HDFS源码分析DataXceiver之整体流程

    在<HDFS源码分析之DataXceiverServer>一文中,我们了解到在DataNode中,有一个后台工作的线程DataXceiverServer.它被用于接收来自客户端或其他数据节 ...

  3. 编写mipsel mt7620 Led驱动(一)

    1.看原理图中知芯片上66引脚控制一个LED 2.在Datasheet中找出GPIO pin 3.在ProgrammingGuid  System Contrl中找到GPIO控制寄存器地址: 4.控制 ...

  4. MongoDB水平分片集群(转)

    为何需要水平分片 1 减少单机请求数,将单机负载,提高总负载 2 减少单机的存储空间,提高总存空间. 下图一目了然: mongodb sharding 服务器架构 简单注解: 1 mongos 路由进 ...

  5. Top 10 Open Source Bug Tracking System系统

    Bugzilla http://www.bugzilla.org/ Mantis php http://www.mantisbt.org/ Trac Python also provides wiki ...

  6. SSH 使用密钥登录并禁止口令登录

    小结:修改下sshd配置文件,把公钥传上去就好了 先生成公钥和私钥,默认在/root/.ssh/目录,可以先看一下有没有这个目录. 生成公钥后,以后其它服务器也都可以复用这个公钥 最好生成时输入密码! ...

  7. linux查看磁盘挂载的三种方法

    第一种方法:使用df命令,例如: orientalson:/home # df Filesystem 1K-blocks Used Available Use% Mounted on /dev/sda ...

  8. 继承ViewGroup类

    Android中,布局都是直接或间接的继承自ViewGroup类,其中,ViewGroup的直接子类目前有: AbsoluteLayout, AdapterView<T extends Adap ...

  9. android -volley-请求数据

    private List<gson.DataBean>arrGson;//请求的数据 //请求数据的方法 public void initData() { RequestQueue mQu ...

  10. python 基础 8.0 regex 正则表达式--常用的正则表达式

    一. python 中常用的正则表达式         二. 正则表达式的网站,可以进行在线正则匹配 https://regex101.com/   1. 使用方法及正则介绍 1> ‘.’  匹 ...