什么叫分层图最短路,我不会/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. MongoDB从bson文件中恢复数据

    首先需要到mangodb的安装目录的bin下面找到mongorestore.exe WIN10系统MongoDB安装目录bin文件夹下没有mongorestore.exe 先下载工具  https:/ ...

  2. spring security简介与使用

    目录 spring security 新建一个springboot项目 添加spring security 登录 使用默认用户和随机生成的密码登录 使用yaml文件定义的用户名.密码登录 使用代码中指 ...

  3. window.location.href用法与a标签的比较

    1.在使用这两种方法进行页面的跳转时,这两种方法都能够有效的实现该功能 但是其原理不尽相同 第一:window.location.href()方法必须书写在js中 <html> <h ...

  4. Java 值传递 or 引用传递?

    Java 方法传参 值传递 or 引用传递? 结论:Java采用的是值传递 先建立一些基础的概念 什么是值传递和引用传递? 值传递(pass by value):是指在调用函数时将实际参数复制一份传递 ...

  5. Vulnhub 之 Earth

    靶机地址:https://www.vulnhub.com/entry/the-planets-earth,755/ Kali IP:192.168.56.104 下载OVA文件后,直接通过Virtua ...

  6. python2.7安装pyinstaller

    python2.7直接安装pyinstaller会报错,版本4与python2不兼容,所以我们安装时需指定兼容的pyinstaller版本号.安装命令如下: pip2 install pyinstal ...

  7. zabbix使用自带模板监控MySQL

    监控mysql不能直接使用zabbix自带模板,还需要到被监控的mysql客户端做配置. 1.在zabbix   web配置步骤如下图: 2.配置完之后去看mysql主机监控项的时候看到mysql的监 ...

  8. Linux shell中2>&1的含义解释

    https://blog.csdn.net/zhaominpro/article/details/82630528

  9. 自定义user表签发token、自定义认证类、simpleui模块使用

    今日内容概要 自定义User表,签发token 自定义认证类 simpleui的使用 多方式登陆接口(后面也写 内容详细 1.自定义User表,签发token # 如果项目中的User表使用auth的 ...

  10. Luffy /3/ 前台主页搭建&轮播图接口

    目录 前台主页搭建 components/Homeviwe.vue components/Banner.vue components/Header.vue components/Footer.vue ...