Distance Queries 距离咨询 (LCA倍增模板)
农夫约翰有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;
}
最新文章
- java父类与接口有相同的方法
- SSH框架搭建
- Python-Day3知识点——深浅拷贝、函数基本定义、内置函数
- Visual Studio最好用的快捷键
- 使用iframe 或frameset框架退出不成功
- Swift学习--常量.变量.数据类型的使用(二)
- JavaScript 语言基础知识点总结(思维导图)
- easyui toolbar 可以放在datagrid底下
- json解析日期方法 问题的解决方案
- 【转】Linux I2C设备驱动编写(二)
- 使程序能够引入.json文件, 为网站添加 MIME 映射
- Java 抽象工厂模式
- Event notifications
- nginx 499状态码
- ip通信第七周
- Markdown介绍及工具推荐
- 【漏洞分析】两个例子-数组溢出修改返回函数与strcpy覆盖周边内存地址
- 通俗理解caller和callee
- 数据库savepoint
- 字符串hash&;&;对字符串hash的理解