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

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

Http

POJ:https://vjudge.net/problem/POJ-1986

UESTC:https://vjudge.net/problem/UESTC-256

Source

最近公共祖先LCA

题目大意

在一棵边带权的树上回答若干个两点之间距离的询问

解决思路

这题当然是用floyed解啦

(以上纯属胡扯)

在树上求两点之间的距离何必用Floyed呢?我们有LCA。

那么如何用LCA解这道题呢?关于LCA倍增算法的基本思路请参照我的这篇文章

但上文讲述的是边不带权的情况,本题中,我们要做一些改变。

首先,为了方便起见,我们设根节点为1号点,那么Depth和Parent的定义都没有变,我们再加上一个Dist[u]表示u到1的距离(注意和Depth的区别,一个是深度,记录节点数,另一个是距离,记录边权和)

那么两个点之间的距离就是Dist[u]+Dist[v]-2*Dist[LCA(u,v)]啦。

简单解释一下,设u和v的最近公共祖先为p,u和v的距离首先可以是u到p的距离+v到p的距离,而u到p的距离又可以是Dist[u]-Dist[p],v也同理,所以两式相加就可以得到上面的式子了。

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std; class Edge
{
public:
int v,w;
}; const int maxN=210000;
const int inf=2147483647; int n,m;
vector<Edge> E[maxN];
int Depth[maxN];
int Dist[maxN];
int Parent[maxN][23];
bool vis[maxN]; void LCA_init();
void dfs(int u);
int LCA(int a,int b); int main()
{
cin>>n>>m;
for (int i=1;i<=m;i++)
{
int a,b,c;
char ch;
scanf("%d%d%d",&a,&b,&c);
cin>>ch;
E[a].push_back((Edge){b,c});
E[b].push_back((Edge){a,c});
}
LCA_init();
int Q;
scanf("%d",&Q);
for (int i=1;i<=Q;i++)
{
int u,v;
scanf("%d%d",&u,&v);
cout<<Dist[u]+Dist[v]-2*Dist[LCA(u,v)]<<endl;
}
return 0;
} void LCA_init()
{
memset(Dist,0,sizeof(Dist));
memset(Parent,0,sizeof(Parent));
memset(Depth,0,sizeof(Depth));
memset(vis,0,sizeof(vis));
dfs(1);
for (int j=1;j<=20;j++)
for (int i=1;i<=n;i++)
Parent[i][j]=Parent[Parent[i][j-1]][j-1];
return;
} void dfs(int u)
{
vis[u]=1;
for (int i=0;i<E[u].size();i++)
{
int v=E[u][i].v;
if (vis[v]==0)
{
Depth[v]=Depth[u]+1;
Dist[v]=Dist[u]+E[u][i].w;
Parent[v][0]=u;
dfs(v);
}
}
return;
} int LCA(int a,int b)
{
if (Depth[a]<Depth[b])
swap(a,b);
for (int i=20;i>=0;i--)
if ((Parent[a][i]!=0)&&(Depth[Parent[a][i]]>=Depth[b]))
a=Parent[a][i];
if (a==b)
return a;
for (int i=20;i>=0;i--)
if ((Parent[a][i]!=0)&&(Parent[b][i]!=0)&&(Parent[a][i]!=Parent[b][i]))
{
a=Parent[a][i];
b=Parent[b][i];
}
return Parent[a][0];
}

POJ 1986 Distance Queries / UESTC 256 Distance Queries / CJOJ 1129 【USACO】距离咨询(最近公共祖先)的更多相关文章

  1. POJ 1986 Distance Queries(Tarjan离线法求LCA)

    Distance Queries Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 12846   Accepted: 4552 ...

  2. POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA)

    POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA) Description A ...

  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 (Tarjan算法求最近公共祖先)

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

  6. 【LCA求最近公共祖先+vector构图】Distance Queries

    Distance Queries 时间限制: 1 Sec  内存限制: 128 MB 题目描述 约翰的奶牛们拒绝跑他的马拉松,因为她们悠闲的生活不能承受他选择的长长的赛道.因此他决心找一条更合理的赛道 ...

  7. pdo mysql错误:Cannot execute queries while other unbuffered queries are active

    运行环境:PHP 5.5.30-x64,MYSQL  5.6.27 错误代码:Cannot execute queries while other unbuffered queries are act ...

  8. POJ 1986(LCA and RMQ)

    题意:给定一棵树,求任意两点之间的距离. 思路:由于树的特殊性,所以任意两点之间的路径是唯一的.u到v的距离等于dis(u) + dis(v) - 2 * dis(lca(u, v)); 其中dis( ...

  9. [最近公共祖先] POJ 3728 The merchant

    The merchant Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 4556   Accepted: 1576 Desc ...

随机推荐

  1. 01 json环境搭建

    1 导包 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.o ...

  2. cpp命名空间

    1.namespace:c++里面的所有标识符都被定义到名为std的namespace中,命名空间就是标识符的各种可见范围,控制其作用域. 2.std为c++标准命名空间,c++标准库里的标识符都定义 ...

  3. stat命令

  4. java面试题之int和Integer的区别

    int和Integer的区别 1.Integer是int的包装类,int则是java的一种基本数据类型 2.Integer变量必须实例化后才能使用,而int变量不需要 3.Integer实际是对象的引 ...

  5. DDD理论学习系列(5)-- 统一建模语言

    DDD理论学习系列--案例及目录 1.引言 上一节讲解了领域模型,领域模型主要是将业务中涉及到的概念以面向对象的思想进行抽象,抽象出实体对象,确定实体所对应的方法和属性,以及实体之间的关系.然后将这些 ...

  6. PHP的面向对象 — 封装、继承、多态

    K在上一次的基础篇中给大家介绍了一下关于PHP中数组和字符串的使用方法等,这一次,K决定一次性大放送,给大家分享一下PHP中面向对象的三大特性:封装.继承.多态三个方面的知识. 一.封装 在PHP中, ...

  7. Java IO学习笔记一

    Java IO学习笔记一 File File是文件和目录路径名的抽象表示形式,总的来说就是java创建删除文件目录的一个类库,但是作用不仅仅于此,详细见官方文档 构造函数 File(File pare ...

  8. Cordova各个插件使用介绍系列(四)—canvas2ImagePlugin保存二维码到手机本地

    详情链接地址:http://www.ncloud.hk/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/cordova-4-canvas2imageplugin/ 在前面几篇 ...

  9. HTML特殊布局--------双飞翼布局

    今天看到以前写的一篇布局的例子分享给大家,双飞翼布局. 什么是双飞翼布局?? 1.三列布局,中间宽度自适应,两边固定宽度; 2.中间栏在浏览器中优先展示渲染: 双飞翼布局的原理: 中间的盒子定100% ...

  10. test_markdown

    add modifications 非科学计数法显示数字 citation[^ref1] format bank% do not use scientific expression format lo ...