什么叫分层图最短路,我不会/kk

感觉自己做法和其他题解不大一样所以过来发篇题解了。

未刻意卡常拿下最优解

题目大意

就是说给你一个 \(n \times n\) 的网格图和 \(m\) 个可换乘点,然后你只能在同一行或同一列(如果在行上移动,就不能在列上移动;反之同理)上移动,除非这个点是可以换乘的。每次走一格花费 \(2\) 费,换乘花费 \(1\) 费,求从 \((sx,sy)\) 到 \((fx,fy)\) 的最小费用。

其中:\(n \leqslant 20000,m \leqslant 100000\)

分析

可以发现如果对于每个格点都存储信息是不可行的,我们考虑优化空间:发现我们的路径实际上就是一直冲,然后只有在部分换乘点转弯,所以我们可以把换乘点联系起来,在换乘点之间跑最短路。

具体做法

那么具体怎么做呢,我们考虑对于每行和每列开领接表,存储这一行或这一列上,存在的换乘点的编号。然后可以把起始点也看做换乘点。然后跑最短路的时候就直接通过两点的距离\(\times 2 + 1\) 来转移最短路距离(因为我们去换乘点便是为了转弯),最后输出 \(dis[\) 终点编号 \(]-1\)即可(\(-1\) 是为了把在终点转弯的费用减掉)。最后注意数组大小别开错就行了。(我因为这个WA了一发)

那么看代码吧!

Code:

#include<bits/stdc++.h>
using namespace std;
inline int read(){
int s=0,f=1;
char ch=getchar();
while(ch<'0'||'9'<ch) {if(ch=='-') f=-1;ch=getchar();}
while('0'<=ch&&ch<='9') {s=s*10+(ch^48);ch=getchar();}
return s*f;
}
inline int dist(int x,int y){
return x>y?x-y:y-x;
}
const int INF=1e9;
const int N=20000+3;
const int M=100002+3;
struct node{
int x,y;
}p[M];
int n,m;
int sx,sy,fx,fy;
queue<int>q;
int dis[M];
bool inq[M];
vector<int>h[N],l[N];
inline void SPFA(){//最短路
q.push(1);inq[1]=1;
for(int i=1;i<=m+2;++i){
dis[i]=INF;
}
dis[1]=0;
while(!q.empty()){
int u=q.front();q.pop();inq[u]=0;
int lena=h[p[u].x].size(),lenb=l[p[u].y].size();
//考虑转弯,可以发现往回走是不优的,但是都不违反题意,所以行列都跑一遍也没事。
for(int i=0;i<lena;++i){
int v=h[p[u].x][i],val=dist(p[v].y,p[u].y)*2+1;//费用计算
if(v==u) continue;
if(dis[v]>=dis[u]+val){
dis[v]=dis[u]+val;
if(!inq[v]){
inq[v]=1;
q.push(v);
}
}
}
for(int i=0;i<lenb;++i){
int v=l[p[u].y][i],val=dist(p[v].x,p[u].x)*2+1;
if(u==v) continue;
if(dis[v]>=dis[u]+val){
dis[v]=dis[u]+val;
if(!inq[v]){
q.push(v);
inq[v]=1;
}
}
}
}
}
int main(){
n=read();m=read();
for(int i=2;i<=m+1;++i){
p[i].x=read();p[i].y=read();
h[p[i].x].push_back(i);
l[p[i].y].push_back(i);//类似领接表的东西
}
sx=read();sy=read();fx=read();fy=read();
h[sx].push_back(1);l[sy].push_back(1);
h[fx].push_back(m+2);l[fy].push_back(m+2);//把起始点当做换乘点
p[1]={sx,sy};p[m+2]={fx,fy};
SPFA();
if(dis[m+2]!=INF) printf("%d\n",dis[m+2]-1);//除去多余的最后一次转弯费用
else printf("-1\n");//无法到达输-1
return 0;
}

似乎比其他题解的做法简单一些?

题解 P3831 [SHOI2012]回家的路的更多相关文章

  1. P3831 [SHOI2012]回家的路

    P3831 [SHOI2012]回家的路 分层图基础题,就是建图稍有麻烦   #include<cstdio> #include<algorithm> #include< ...

  2. [SHOI2012]回家的路

    题目背景 SHOI2012 D2T1 题目描述 2046 年 OI 城的城市轨道交通建设终于全部竣工,由于前期规划周密,建成后的轨道交通网络由2n2n条地铁线路构成,组成了一个nn纵nn横的交通网.如 ...

  3. [SHOI2012]回家的路 最短路

    ---题面--- 题解: 吐槽:找了好久的错,换了n种方法,重构一次代码,,,, 最后发现,,, 数组开小了,其实一开始尝试开大了数组,但唯独没有尝试开大手写队列的数组.... 思路: 有两种方法,这 ...

  4. 分层图最短路【bzoj2834】: 回家的路

    分层图最短路[bzoj2834]: 回家的路 题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2834 这道题难在建边. 自己写的时候想到了 ...

  5. Bzoj 2834: 回家的路 dijkstra,堆优化,分层图,最短路

    2834: 回家的路 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 62  Solved: 38[Submit][Status][Discuss] D ...

  6. bzoj 2834: 回家的路

    题目 F.A.Qs Home Discuss ProblemSet Status Ranklist Contest 入门OJ ModifyUser  DCOI Logout 捐赠本站 Notice:1 ...

  7. 洛谷P3831 回家的路

    题目背景 SHOI2012 D2T1 题目描述 \(2046\) 年 \(OI\) 城的城市轨道交通建设终于全部竣工,由于前期规划周密,建成后的轨道交通网络由\(2n\)条地铁线路构成,组成了一个\( ...

  8. 【bzoj2834】回家的路 分层图最短路

    题目描述 输入 输出 样例输入 2 1 1 2 1 1 2 2 样例输出 5 题解 分层图最短路 dis[i][0]表示到i为横向时起点到i的最短路,dis[i][1]表示到i为纵向时起点到i的最短路 ...

  9. BZOJ.2834.回家的路(最短路Dijkstra 拆点)

    题目链接 对于相邻的.处在同在一行或一列的车站连边,然后用dis[x][0/1](或者拆点)分别表示之前是从横边还是竖边到x的,跑最短路. 我选择拆点.. //13028kb 604ms #inclu ...

随机推荐

  1. JavaScript正则进阶之路——活学妙用奇淫正则表达式

    原文收录在我的 GitHub博客 (https://github.com/jawil/blog) ,喜欢的可以关注最新动态,大家一起多交流学习,共同进步,以学习者的身份写博客,记录点滴. 有些童鞋肯定 ...

  2. snippet,让你编码效率翻倍

    为什么谈到Snippet 今天下午在用vscode做小程序的时候,发现很不方便,因为商店里提供的代码片段极为有限,而且平时几乎每天都需要用到代码片段,所以就在思考他们是怎么做到给别人提供代码的,我可以 ...

  3. ubantu系统之快捷键使用

    1. 文件管理器中,目录切换为可以编辑的状态: ctrl + l 2. gedit 搜索 : ctrl + h

  4. jquery 常用选择器和方法以及遍历(超详细)

    jQuery 常用选择器和和方法 学习总结 一.JQuery 介绍 1. 什么是 jQuery 2. jQuery 版本介绍 3. jQuery 文件介绍 二.jQuery 对象 1. jQuery ...

  5. MySQL外键约束On Delete和On Update的使用

    On Delete和On Update都有Restrict,No Action, Cascade,Set Null属性.现在分别对他们的属性含义做个解释. ON DELETE restrict(约束) ...

  6. Centos搭建 Docker 环境

    搭建 Docker 环境 安装与配置 Docker 安装 Docker Docker 软件包已经包括在默认的 CentOS-Extras 软件源里.因此想要安装 docker,只需要运行下面的 yum ...

  7. 最长非降子序列的N*logN解法

    之前讲到过求最长非降子序列的O(N^2)解法. 链接 这次在原来的基础上介绍一下N*logN解法. 该解法主要是维护一个数组minValue,minValue[i]表示最长上身子序列长度为i的数的最小 ...

  8. Thinkphp3.2.3 where注入 浅分析漏洞原理及修复

    0x01引子 0x02分析 找到截断方法 找到_parseType的入口 找到生成sql语句的代码 0x03 poc链 0x04 利用示范 payload: http://localhost:3000 ...

  9. Android搞定权限申请

    0x00 前言 使用EasyPermissions库进行申请权限 打开App时就申请权限,如果用户拒绝权限后,会循环申请 如果永久拒绝后,会跳转到设置里继续申请 效果图: 注:不讲原理,先教你怎么实现 ...

  10. Codeforces Round #677 (Div. 3) D. Districts Connection思维1200

    题目链接 Problem - 1433D - Codeforces 题目 美好的一天,从看不懂题目开始~~ Example input 4 5 1 2 2 1 3 3 1 1 1 4 1 1000 1 ...