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. 卡特兰数-Catalan数

    卡特兰数的含义: 说到卡特兰数,就不得不提及卡特兰数序列.卡特兰数序列是一个整数序列.其通项公式是我们从中取出的就叫做第n个卡特兰数数,前几个卡特兰数数是:1, 1, 2, 5, 14, 42, 13 ...

  2. 集群 安装 配置FastDFS

    FastDFS 集群 安装 配置 这篇文章介绍如何搭建FastDFS 集群 FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储.文件同步.文件访问(文件上传.文件下载 ...

  3. Python 进程、线程、协程、锁机制,你知多少?

    1.python的多线程到底有没有用? 2. 为什么在python里推荐使用多进程而不是多线程 3.进程.线程.协程.各种锁 4.Python多进程编程

  4. 九度OJ 1178:复数集合 (插入排序)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:8393 解决:1551 题目描述: 一个复数(x+iy)集合,两种操作作用在该集合上: 1.Pop 表示读出集合中复数模值最大的那个复数,如 ...

  5. Wix Burn运行64位dism.exe的问题

    主要的问题是Burn是一个32位程序,在64位机器上它启动的进程都会被重定向到wow64目录下,也就是说它运行的dism.exe最终会是32位的.解决的方法就是用wix提供的QtExec64CmdLi ...

  6. linux c编程:网络编程

    在网络上,通信服务都是采用C/S机制,也就是客户端/服务器机制.流程可以参考下图: 服务器端工作流程: 使用socket()函数创建服务器端通信套接口 使用bind()函数将创建的套接口与服务器地址绑 ...

  7. FI 常用表

    FI 常用表 GL部分:FAGLFLEXT(FMGLFLEXT)   总账汇总表 GLT0        旧总帐汇总表           SKA1        总账科目主记录 (科目表)      ...

  8. YTST_CX_0001(ALV栏位汇总)

    *********************************************************************** * Title           : X        ...

  9. 关于left join遇到where就不管用的问题

    今天做了个存储过程,需要的功能是查询所有人的得分,有人没分就给零分,显而易见这里用左外连接是没有问题的, 但是在连接完之后有个根据时间筛选功能,于是我加了where条件判断,这时候没有想到的事情发生了 ...

  10. Mongo 分组后排序取时间最大的一整条数据对象

    db.getCollection('product_protocol_new').aggregate([ {$sort:{"end_date":-1}}, {$group:{ _i ...