1588. [USACO Feb04]距离咨询

★★   输入文件:dquery.in   输出文件:dquery.out   简单对比
时间限制:1 s   内存限制:256 MB

【题目描述】

农夫约翰有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的距离。

【来源】

Brian Dean,2004

USACO 2004 February Contest Green Problem 3 Distance Queries

Translate by: 庄乐

天啊 这一道题看起来好难的样子呢  杂么办呢?

唉 谁知道呢

想法一:非常不现实 跑最短路 很显然不超时才怪呢

想法二:呵呵 今天学的 倍增LCA 求最近公共祖先

所以这和这道题到底有什毛关系

。。。。。。。。

首先最短路中不是整了一个dis数组 表示根节点到当前节点的距离吗

所以。。。。。。

首先想法一之所以不可行 是因为还要询问K次(<=10000)所以就是跑最短路的次数未免也太多了

所以。。就是先把dis数组与处理出来  那么只要选定一个点 作为根   然后跑一个dfs遍历一遍 记录dis值

哈哈~想了半天 但是dis数组是计算根节点到i点的距离啊

跟这一题求两点ab之间的距离有啥关系。。。。

倍增LCA是求最近公共祖先

也就是说从最近公共祖先到根节点那一块 是a到根节点路径  和 b到根节点路径  重合的那一部分

停!!++++想出正解了

也就是说   两点之间的距离就是 dis [ a ] +dis [ b ] - 2 * dis [ lca( a,b ) ]

想一想其实也很简单   就是a到根节点的距离-dis [ lca( a,b ) ] 就是a到最近公共祖先的距离

b的也是一样   那么分别求出两点到最近公共祖先的距离 拼起来就是两点之间的距离拉

哈哈 我们再来细化一下代码的具体实现细节

首先我们要建一棵树 假如1号节点是根节点吧

然后一大堆输入嗯嗯嗯

先跑一个dfs 从根节点开始把dis数组求一遍

然后每输入 a b两个点  就直接出答案了~~~~~呵呵呵 真的有这么简单吗 ?? 试试看吧

#include<bits/stdc++.h>
using namespace std;
int n,m,Root=;
const int maxn=;
struct edge{
int to,val;
};
vector<edge> e[maxn];
int dis[maxn],fa[][maxn],Depth[maxn],vis[maxn];
void Addedge(int x,int y,int z){
edge tmp;tmp.to=y;tmp.val=z;
e[x].push_back(tmp);
tmp.to=x;e[y].push_back(tmp);//这是一个双向边
}
void Dfs_dis_set(int rt){
if(rt>n) return;
for(int i=;i<e[rt].size();i++){
int y=e[rt][i].to;
if(vis[y])continue;
vis[y]=;
dis[y]=dis[rt]+e[rt][i].val;
Depth[y]=Depth[rt]+;
Dfs_dis_set(y);
}//初始化dis数组 和Depth数组
}
void Dfs_fa_set(int p){
for(int i=;i<=;++i)
fa[i][p]=fa[i-][fa[i-][p]];
for(int i=;i<e[p].size();i++)
if(e[p][i].to!=fa[][p])
fa[][e[p][i].to]=p,Dfs_fa_set(e[p][i].to);
}
int lca(int x,int y){
if(Depth[x]<Depth[y]) swap(x,y);
int res=Depth[x]-Depth[y];
for(int k=;k>=;k--)
if((<<k)<=res)x=fa[k][x],res-=<<k;
if(x==y)return x;
for(int k=;k>=;k--){
if(fa[k][x]!=fa[k][y])
x=fa[k][x],y=fa[k][y];
}
return fa[][x];
}
int main()
{
freopen("dquery.in","r",stdin);freopen("dquery.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++){
int x,y,z;char c;
cin>>x>>y>>z>>c;
Addedge(x,y,z);//读入,建边
}
dis[]=;Depth[]=;vis[]=;
Dfs_dis_set(); //fa[0][1]=1;
for(int i=;i<=;i++) fa[i][]=;//这一行非常迷
Dfs_fa_set();
int k;scanf("%d",&k);
while(k--){
int a,b;scanf("%d%d",&a,&b);
printf("%d\n",dis[a]+dis[b]-*dis[lca(a,b)]);
// cout<<lca(a,b)<<endl;
}
return ;
}

cogs 1588. [USACO Feb04]距离咨询 倍增LCA的更多相关文章

  1. COGS——T1588. [USACO FEB04]距离咨询

    http://cogs.pro/cogs/problem/problem.php?pid=1588 ★★   输入文件:dquery.in   输出文件:dquery.out   简单对比时间限制:1 ...

  2. usaco feb04距离咨询

    [USACO FEB04]距离咨询 成绩   开启时间 2014年09月19日 星期五 10:08 折扣 0.8 折扣时间 2014年09月26日 星期五 10:08 允许迟交 是 关闭时间 2014 ...

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

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

  4. 约会 倍增lca

    题意:一棵树,给两个点,求树上有多少点到他俩距离相等 倍增lca,分好多情况讨论.. #include<cstdio> #include<cstring> #include&l ...

  5. 2018 ICPC青岛网络赛 B. Red Black Tree(倍增lca好题)

    BaoBao has just found a rooted tree with n vertices and (n-1) weighted edges in his backyard. Among ...

  6. Distance Queries 距离咨询 (LCA倍增模板)

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

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

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

  8. Codeforces 418d Big Problems for Organizers [树形dp][倍增lca]

    题意: 给你一棵有n个节点的树,树的边权都是1. 有m次询问,每次询问输出树上所有节点离其较近结点距离的最大值. 思路: 1.首先是按照常规树形dp的思路维护一个子树节点中距离该点的最大值son_di ...

  9. codevs 1036 商务旅行 (倍增LCA)

    /* 在我还不知道LCA之前 暴力跑的SPFA 70分 三个点TLE */ #include<iostream> #include<cstdio> #include<cs ...

随机推荐

  1. UVA 11584 "Partitioning by Palindromes"(DP+Manacher)

    传送门 •题意 •思路一 定义 dp[i] 表示 0~i 的最少划分数: 首先,用马拉车算法求解出回文半径数组: 对于第 i 个字符 si,遍历 j (0 ≤ j < i),判断以 j 为回文中 ...

  2. ZR1153

    ZR1153 首先我们可以发现一个比较简单的容斥做法 直接暴力枚举\(2^m\)个限制强制不合法,算贡献 注意如果两个限制冲突那么答案为0 直接暴力差分就好了 这样就有了快乐的\(30\)分了 接下来 ...

  3. 关于axios的一些封装

    关于Axios的封装 为何需要在封装 应用场景,项目中涉及100个AJAX请求,其中: 1.其中60个需要在请求头header设置token headers: {token: token}用于权限校验 ...

  4. 2018-8-10-win10-uwp-按下等待按钮

    title author date CreateTime categories win10 uwp 按下等待按钮 lindexi 2018-08-10 19:16:50 +0800 2018-2-13 ...

  5. dotnet 使用 Environment.FailFast 结束程序

    在运行到一些诡异的代码,这时的程序已经无法继续运行,需要退出,那么如何在记完日志之后在退出程序记录更多信息?可以通过 Environment.FailFast 里面添加字符串告诉用户当前的进程无法继续 ...

  6. dotnet 通过 WMI 获取系统安装的驱动

    本文告诉大家如何通过 WMI 获取用户已经安装的驱动程序 通过 Win32_SystemDriver 可以获取用户已经安装的驱动程序 var mc = "Win32_SystemDriver ...

  7. hdu 2454 Degree Sequence of Graph G(可简单图化判定)

    传送门 •Havel-Hakimi定理: 给定一个非负整数序列{d1,d2,...dn},若存在一个无向图使得图中各点的度与此序列一一对应,则称此序列可图化. 进一步,若图为简单图,则称此序列可简单图 ...

  8. 洪强宁:宜信PaaS平台基于Calico的容器网络实践

    洪强宁:宜信PaaS平台基于Calico的容器网络实践   本文内容来自由七牛云主办的ECUG Con,独家授权InfoQ整理完成 容器云面临的网络挑战 在传统的IDC的架构里面网络是很重要的事情,在 ...

  9. centos7 创建sftp

    sftp是Secure File Transfer Protocol的缩写,安全文件传送协议.可以为传输文件提供一种安全的网络的加密方法.sftp 与 ftp 有着几乎一样的语法和功能.SFTP 为  ...

  10. windows键的妙用

    (1)当你需要暂时离开电脑一会儿,怕其余人动你的电脑时,你只需要按windows键+L就可以了,当然前提是你给自己的电脑设置过开机密码. (2)有时候你需要在盘里边找某个文件,但你的桌面上密密麻麻的, ...