题解 P3831 [SHOI2012]回家的路
什么叫分层图最短路,我不会/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]回家的路的更多相关文章
- P3831 [SHOI2012]回家的路
P3831 [SHOI2012]回家的路 分层图基础题,就是建图稍有麻烦 #include<cstdio> #include<algorithm> #include< ...
- [SHOI2012]回家的路
题目背景 SHOI2012 D2T1 题目描述 2046 年 OI 城的城市轨道交通建设终于全部竣工,由于前期规划周密,建成后的轨道交通网络由2n2n条地铁线路构成,组成了一个nn纵nn横的交通网.如 ...
- [SHOI2012]回家的路 最短路
---题面--- 题解: 吐槽:找了好久的错,换了n种方法,重构一次代码,,,, 最后发现,,, 数组开小了,其实一开始尝试开大了数组,但唯独没有尝试开大手写队列的数组.... 思路: 有两种方法,这 ...
- 分层图最短路【bzoj2834】: 回家的路
分层图最短路[bzoj2834]: 回家的路 题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2834 这道题难在建边. 自己写的时候想到了 ...
- Bzoj 2834: 回家的路 dijkstra,堆优化,分层图,最短路
2834: 回家的路 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 62 Solved: 38[Submit][Status][Discuss] D ...
- bzoj 2834: 回家的路
题目 F.A.Qs Home Discuss ProblemSet Status Ranklist Contest 入门OJ ModifyUser DCOI Logout 捐赠本站 Notice:1 ...
- 洛谷P3831 回家的路
题目背景 SHOI2012 D2T1 题目描述 \(2046\) 年 \(OI\) 城的城市轨道交通建设终于全部竣工,由于前期规划周密,建成后的轨道交通网络由\(2n\)条地铁线路构成,组成了一个\( ...
- 【bzoj2834】回家的路 分层图最短路
题目描述 输入 输出 样例输入 2 1 1 2 1 1 2 2 样例输出 5 题解 分层图最短路 dis[i][0]表示到i为横向时起点到i的最短路,dis[i][1]表示到i为纵向时起点到i的最短路 ...
- BZOJ.2834.回家的路(最短路Dijkstra 拆点)
题目链接 对于相邻的.处在同在一行或一列的车站连边,然后用dis[x][0/1](或者拆点)分别表示之前是从横边还是竖边到x的,跑最短路. 我选择拆点.. //13028kb 604ms #inclu ...
随机推荐
- JavaScript正则进阶之路——活学妙用奇淫正则表达式
原文收录在我的 GitHub博客 (https://github.com/jawil/blog) ,喜欢的可以关注最新动态,大家一起多交流学习,共同进步,以学习者的身份写博客,记录点滴. 有些童鞋肯定 ...
- snippet,让你编码效率翻倍
为什么谈到Snippet 今天下午在用vscode做小程序的时候,发现很不方便,因为商店里提供的代码片段极为有限,而且平时几乎每天都需要用到代码片段,所以就在思考他们是怎么做到给别人提供代码的,我可以 ...
- ubantu系统之快捷键使用
1. 文件管理器中,目录切换为可以编辑的状态: ctrl + l 2. gedit 搜索 : ctrl + h
- jquery 常用选择器和方法以及遍历(超详细)
jQuery 常用选择器和和方法 学习总结 一.JQuery 介绍 1. 什么是 jQuery 2. jQuery 版本介绍 3. jQuery 文件介绍 二.jQuery 对象 1. jQuery ...
- MySQL外键约束On Delete和On Update的使用
On Delete和On Update都有Restrict,No Action, Cascade,Set Null属性.现在分别对他们的属性含义做个解释. ON DELETE restrict(约束) ...
- Centos搭建 Docker 环境
搭建 Docker 环境 安装与配置 Docker 安装 Docker Docker 软件包已经包括在默认的 CentOS-Extras 软件源里.因此想要安装 docker,只需要运行下面的 yum ...
- 最长非降子序列的N*logN解法
之前讲到过求最长非降子序列的O(N^2)解法. 链接 这次在原来的基础上介绍一下N*logN解法. 该解法主要是维护一个数组minValue,minValue[i]表示最长上身子序列长度为i的数的最小 ...
- Thinkphp3.2.3 where注入 浅分析漏洞原理及修复
0x01引子 0x02分析 找到截断方法 找到_parseType的入口 找到生成sql语句的代码 0x03 poc链 0x04 利用示范 payload: http://localhost:3000 ...
- Android搞定权限申请
0x00 前言 使用EasyPermissions库进行申请权限 打开App时就申请权限,如果用户拒绝权限后,会循环申请 如果永久拒绝后,会跳转到设置里继续申请 效果图: 注:不讲原理,先教你怎么实现 ...
- 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 ...