农夫约翰有N(2<=N<=40000)个农场,标号1到N。M(2<=M<=40000)条的不同的垂直或水平的道路连结着农场,道路的长度不超过1000.这些农场的分布就像下面的地图一样,图中农场用F1..F7表示:

每个农场最多能在东西南北四个方向连结4个不同的农场。此外,农场只处在道路的两端。道路不会交叉而且每对农场间有且仅有一条路径。邻居鲍伯要约翰来导航,但约翰丢了农场的地图,他只得从电脑的备份中修复率。每一条道路的信息如下:

    从农场23往南经距离10到达农场17
从农场1往东经距离7到达农场17

. . .

最近美国过度肥胖非常普遍。农夫约翰为了让他的奶牛多做运动,举办了奶牛马拉松。马拉松路线要尽量长。

奶牛们拒绝跑马拉松,因为她们悠闲的生活无法承受约翰选择的如此长的赛道。因此约翰决心找一条更合理的赛道。他打算咨询你。读入地图之后会有K个问题,每个问题包括2个整数,就是约翰感兴趣的2个农场的编号,请尽快算出这2个农场间的距离。

输入格式

第1行:两个分开的整数N和M。

第2到M+1行:每行包括4个分开的内容,F1,F2,L,D分别描述两个农场的编号,道路的长度,F1到F2的方向N,E,S,W。

第2+M行:一个整数K(1<=K<=10000).

第3+M到2+M+K行:每行输入2个整数,代表2个农场。

输出格式

对每个问题,输出单独的一个整数,给出正确的距离。

样例

样例输入

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

样例输出

13
3
36

样例解释

农场2到农场6有20+3+13=36的距离


析:LCA模板先将 x与y翻到同一深度,然后继续上翻,利用二进制


代码如下:

#include<bits/stdc++.h>
#define ll long long
#define re register int
#define N 500100
using namespace std;
ll sum[N],fa[N][30],p[N][30];
ll to[N<<1],next[N<<1],head[N<<1],w[N<<1];
ll deep[N],dis[N];
ll n,m,k,tot;
ll a,b,c;
char ch[5];
void add(ll x,ll y,ll z)
{
    to[++tot]=y;
    next[tot]=head[x];
    head[x]=tot;
    w[tot]=z;
}
void bfs(ll x,ll f)
{
    for(re i=1;(1<<i)<=n;i++)
        fa[x][i]=fa[fa[x][i-1]][i-1];
    for(re i=head[x];i;i=next[i])
    {
        ll p=to[i];
        if(p==f)
            continue;
        deep[p]=deep[x]+1;
        dis[p]=dis[x]+w[i];
        fa[p][0]=x;
        bfs(p,x);
    }
}
ll lca(ll x,ll y)
{
    if(deep[x]<deep[y])
        return lca(y,x);
    ll d=deep[x]-deep[y];
    for(re i=0;(1<<i)<=d;i++)
        if((1<<i)&d)
            x=fa[x][i];
    if(x==y)
        return x;
    for(re i=18;i>=0;i--)
        if(fa[x][i]!=fa[y][i])
        {
            x=fa[x][i];
            y=fa[y][i];
        }
    return fa[x][0];
}
int main()
{
    scanf("%lld%lld",&n,&m);
    for(re i=1;i<=m;i++)
    {
        scanf("%lld%lld%lld%s",&a,&b,&c,ch);
        add(a,b,c);
        add(b,a,c);
    }
    bfs(1,0);
    scanf("%lld",&k);
    while(k--)
    {
        scanf("%lld%lld",&a,&b);
        //cout<<"dis[a]="<<dis[a]<<" dis[b]="<<dis[b]<<" dis[lca]="<<dis[lca(a,b)]<<" lca="<<lca(a,b)<<endl;
        printf("%lld\n",dis[a]+dis[b]-2*dis[lca(a,b)]);
    }
    return 0;
}

Distance Queries 距离咨询 (LCA倍增模板)的更多相关文章

  1. LCA【bzoj3364】 [Usaco2004 Feb]Distance Queries 距离咨询

    Description  奶牛们拒绝跑马拉松,因为她们悠闲的生活无法承受约翰选择的如此长的赛道.因此约翰决心找一条更合理的赛道,他打算咨询你.此题的地图形式与前两题相同.但读入地图之后,会有K个问题. ...

  2. BZOJ 3364: [Usaco2004 Feb]Distance Queries 距离咨询

    Description 一棵树,询问两点间距离. Sol 倍增. 方向没用. 没有然后了. Code /************************************************ ...

  3. poj 1986 Distance Queries 带权lca 模版题

    Distance Queries   Description Farmer John's cows refused to run in his marathon since he chose a pa ...

  4. 【 lca倍增模板】

    题目描述 对于 n(<100000)个点 n-1 条掉权值的边,有 m 个询问,每条询问求两个结点之间的路径上边权的最小值 输入 第一行 n,表示结点个数,接下来 n-1 行,每行 a b w ...

  5. LCA倍增算法

    LCA 算法是一个技巧性很强的算法. 十分感谢月老提供的模板. 这里我实现LCA是通过倍增,其实就是二进制优化. 任何一个数都可以有2的阶数实现 例如16可以由1 2 4 8组合得到 5可以由1 2 ...

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

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

  7. cogs 1588. [USACO Feb04]距离咨询 倍增LCA

    1588. [USACO Feb04]距离咨询 ★★   输入文件:dquery.in   输出文件:dquery.out   简单对比时间限制:1 s   内存限制:256 MB [题目描述] 农夫 ...

  8. POJ1986 Distance Queries (LCA)(倍增)

    Distance Queries Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 12950   Accepted: 4577 ...

  9. POJ 1986 - Distance Queries - [LCA模板题][Tarjan-LCA算法]

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

随机推荐

  1. KDE桌面环境下konsole,kate等软件无法切换中文输入法

    解决方案(arch): 修改/etc/profile,增加以下语句: #fcitxexport XIM_PROGRAM=fcitxexport XIM=fcitxexport GTK_IM_MODUL ...

  2. uni-app中组件picker的基本使用(日期选择器为例)

    例:需要在下图"自定义日期"中使用日期选择器 <template> <div> <picker mode="date" @chan ...

  3. CG-CTF 480小时精通C++

    一.拖入ida,看看 和之前题,有点不一样,不一样在于,这个程序相等于将没加密的字符串,直接打印出来了,但是The Encrypted is 引起了我的注意,所以我去看看有没加密函数,结果还真有,一堆 ...

  4. 十九、.net core使用SoapCore开发webservice接口,以及使用HttpClientFactory动态访问webservice接口

    使用SoapCore实现在.net core平台下开发webservice:以及使用HttpClientFactory动态访问webservice. 首先,需要在包项目下面引用SoapCore: 然后 ...

  5. Java | 标识符 & 关键字

    标识符是什么? 标识符 标识符是指在程序中,我们自己定义的内容.比如类的名字.方法的名字和变量的名字等等,都是标识符.在我们写的第一个程序当中,我们给类起名叫做Hello 也叫做标识符. 命名规则 标 ...

  6. Nginx的安装和部署

    Nginx简介 Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行.其特点是占有内存少,并发能力强,事实上nginx的并发 ...

  7. docker容器技术基础之linux cgroup、namespace

    一.开头 接触过docker的同学多多少少听过这样一句话"docker容器通过linux namespace.cgroup特性实现资源的隔离与限制".今天我们来尝试学习一下这两个东 ...

  8. MapReduce处理简单数据

    首先要说明的是,关于老师给的实验要求,我在网上看到了原文,原文地址:https://blog.csdn.net/qq_41035588/article/details/90514824,有兴趣的同学可 ...

  9. 10分钟系列:NetCore3.1+EFCore三步快速完成数据库交互

    前言 做程序开发,不管是什么语言什么数据库,其中的ORM(对象关系映射)是必不可少的,但是不管选择哪一种ORM,都需要了解其中的运行机制,配置帮助类等等. 所以很多ORM都开始进行升级封装,我们只需要 ...

  10. MapReduce学习总结之java版wordcount实现

    一.代码实现: package rdb.com.hadoop01.mapreduce; import java.io.IOException; import org.apache.hadoop.con ...