Distance Queries
Time Limit: 2000MS   Memory Limit: 30000K
Total Submissions: 12846   Accepted: 4552
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

Hint

Farms 2 and 6 are 20+3+13=36 apart. 

题目连接:POJ 1986

简单模版题,一棵树中两点的距离$d(u,v)$可以用$d[u]+d[v]-2*d[lca(u,v)]$来求得,其中$d_i$是你设定的根到某一点$i$的距离,那显然首先随便找个点进行最短路或者直接DFS获得d数组,再Tarjan得出答案

代码:

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <sstream>
#include <cstring>
#include <bitset>
#include <string>
#include <deque>
#include <stack>
#include <cmath>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
typedef pair<int,int> pii;
typedef long long LL;
const double PI=acos(-1.0);
const int N=40010;
struct edge
{
int to;
int nxt;
int w;
};
struct query
{
int to;
int nxt;
int id;
}; edge E[N<<1];
query Q[N<<1];
int head[N],rhead[N],tot,rtot;
int d[N],dx[N],vis[N],in[N];
int pre[N],ances[N]; void init()
{
CLR(head,-1);
CLR(rhead,-1);
tot=rtot=0;
CLR(d,0);
for (int i=0; i<N; ++i)
{
pre[i]=i;
ances[i]=0;
}
CLR(vis,0);
CLR(in,0);
CLR(dx,0);
}
int Find(int n)
{
if(pre[n]==n)
return n;
return pre[n]=Find(pre[n]);
}
inline void add(int s,int t,int d)
{
E[tot].to=t;
E[tot].w=d;
E[tot].nxt=head[s];
head[s]=tot++;
}
inline void addquery(int s,int t,int id)
{
Q[rtot].id=id;
Q[rtot].to=t;
Q[rtot].nxt=rhead[s];
rhead[s]=rtot++;
}
void LCA(int u)
{
vis[u]=1;
ances[u]=u;
int i,v;
for (i=head[u]; ~i; i = E[i].nxt)
{
v = E[i].to;
if(!vis[v])
{
LCA(v);
pre[v]=u;
ances[Find(u)]=u;
}
}
for (i=rhead[u]; ~i; i = Q[i].nxt)
{
v=Q[i].to;
if(vis[v])
dx[Q[i].id]=d[u]+d[v]-(d[ances[Find(v)]]<<1);
}
}
void dfs(int u,int fa,int sum)
{
d[u]=sum;
for (int i=head[u]; ~i; i = E[i].nxt)
{
int v=E[i].to;
if(v!=fa)
dfs(v,u,sum+E[i].w);
}
}
int main(void)
{
int n,m,a,b,c,i,k;
char nouse[5];
while (~scanf("%d%d",&n,&m))
{
init();
for (i=0; i<m; ++i)
{
scanf("%d%d%d%s",&a,&b,&c,nouse);
add(a,b,c);
add(b,a,c);
++in[b];
}
scanf("%d",&k);
for (i=0; i<k; ++i)
{
scanf("%d%d",&a,&b);
addquery(a,b,i);
addquery(b,a,i);
}
for (i=1; i<=n; ++i)
{
if(!in[i])
{
dfs(i,-1,0);
LCA(i);
break;
}
}
for (i=0; i<k; ++i)
printf("%d\n",dx[i]);
}
return 0;
}

POJ 1986 Distance Queries(Tarjan离线法求LCA)的更多相关文章

  1. POJ - 1986 Distance Queries(离线Tarjan算法)

    1.一颗树中,给出a,b,求最近的距离.(我没考虑不联通的情况,即不是一颗树的情况) 2.用最近公共祖先来求, 记下根结点到任意一点的距离dis[],这样ans = dis[u] + dis[v] - ...

  2. POJ 1986 Distance Queries / UESTC 256 Distance Queries / CJOJ 1129 【USACO】距离咨询(最近公共祖先)

    POJ 1986 Distance Queries / UESTC 256 Distance Queries / CJOJ 1129 [USACO]距离咨询(最近公共祖先) Description F ...

  3. POJ.1986 Distance Queries ( LCA 倍增 )

    POJ.1986 Distance Queries ( LCA 倍增 ) 题意分析 给出一个N个点,M条边的信息(u,v,w),表示树上u-v有一条边,边权为w,接下来有k个询问,每个询问为(a,b) ...

  4. POJ 1986 Distance Queries LCA两点距离树

    标题来源:POJ 1986 Distance Queries 意甲冠军:给你一棵树 q第二次查询 每次你问两个点之间的距离 思路:对于2点 u v dis(u,v) = dis(root,u) + d ...

  5. POJ 1986 Distance Queries 【输入YY && LCA(Tarjan离线)】

    任意门:http://poj.org/problem?id=1986 Distance Queries Time Limit: 2000MS   Memory Limit: 30000K Total ...

  6. POJ 1986 Distance Queries(LCA Tarjan法)

    Distance Queries [题目链接]Distance Queries [题目类型]LCA Tarjan法 &题意: 输入n和m,表示n个点m条边,下面m行是边的信息,两端点和权,后面 ...

  7. POJ 1986 Distance Queries (Tarjan算法求最近公共祖先)

    题目链接 Description Farmer John's cows refused to run in his marathon since he chose a path much too lo ...

  8. POJ 1986 Distance Queries (最近公共祖先,tarjan)

    本题目输入格式同1984,这里的数据范围坑死我了!!!1984上的题目说边数m的范围40000,因为双向边,我开了80000+的大小,却RE.后来果断尝试下开了400000的大小,AC.题意:给出n个 ...

  9. poj 1986 Distance Queries LCA

    题目链接:http://poj.org/problem?id=1986 Farmer John's cows refused to run in his marathon since he chose ...

随机推荐

  1. 07 JavaWeb

    软件开发的两种架构:c/s和b/s          * C/S     client/server     客户端/服务器     例子:QQ     快播     暴风影音...          ...

  2. js获取一个对象的所以属性和值

    在HTML DOM中,获取某个元素对象的时候,往往记不住它的很多属性,可以通过下面的例子来查找一下: <!DOCTYPE html> <html> <body> & ...

  3. sprint3冲刺第一天

    1.计划了sprint3要做的内容: 整合前台和后台,然后发布让用户使用,然后给我们反馈再进行改进 2.backlog表格: ID 任务 Est 做了什么 1 实现用户登录与权限判定 4 进行用户分类 ...

  4. Thread 的使用

    对于Thread 的使用,我要注意的是我经常忽略".start()".之前由于在android开发中,如果是使用网络加载的功能,这个部分需要新增线程,不能在主线程使用. 然后注意要 ...

  5. 【oracle】解锁oracle用户,unlock

    解除oracle用户的锁定状态,例如oracle数据库建立测试实例时默认建立的scott用户,一开始是处于locked状态的,现在我们需要将其解锁,步骤如下: (1)在cmd中登录sqlplus,例如 ...

  6. BZOJ3764 : Petya的序列

    首先如果一段连续子序列里没有任何幸运数,那么显然可以缩成一个点. 设幸运数个数为$m$,那么现在序列长度是$O(m)$的,考虑暴力枚举$R_1$,然后从右往左枚举$L_1$. 每次碰到一个幸运数,就将 ...

  7. hive0.12 rcfile gzip 测试

    创建test_rc; 让后从老数据中插入test_rc中, select test_rc 中插入的数据,报如下错误: Failed with exception java.io.IOException ...

  8. html5代码,获取地理位置

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <meta htt ...

  9. ACM Binary String Matching

    Binary String Matching 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 Given two strings A and B, whose alp ...

  10. BZOJ1391: [Ceoi2008]order

    Description 有N个工作,M种机器,每种机器你可以租或者买过来. 每个工作包括若干道工序,每道工序需要某种机器来完成,你可以通过购买或租用机器来完成. 现在给出这些参数,求最大利润 Inpu ...