题目背景

SHOI2012 D2T1

题目描述

\(2046\) 年 \(OI\) 城的城市轨道交通建设终于全部竣工,由于前期规划周密,建成后的轨道交通网络由\(2n\)条地铁线路构成,组成了一个\(n\)纵\(n\)横的交通网。如下图所示,这\(2n\)条线路每条线路都包含\(n\)个车站,而每个车站都在一组纵横线路的交汇处。

出于建设成本的考虑,并非每个车站都能够进行站内换乘,能够进行站内换乘的地铁站共有\(m\)个,在下图中,标上方块标记的车站为换乘车站。已知地铁运行 \(1\) 站需要 \(2\) 分钟,而站内换乘需要步行 \(1\) 分钟。\(Serenade\) 想要知道,在不中途出站的前提下,他从学校回家最快需要多少时间(等车时间忽略不计)。

输入输出格式

输入格式:

第一行有两个整数\(n,m\)。

接下去\(m\)行每行两个整数\(x,y\),表示第\(x\)条横向线路与第\(y\)条纵向线路的交

汇站是站内换乘站。

接下去一行是四个整数\(x_1,y_1,x_2,y_2\)。表示 \(Serenade\) 从学校回家时,在第 \(x_1\)条横向线路与第\(y_1\)​条纵向线路的交汇站上车,在第\(x_2\)​条横向线路与第\(y_2\)​条纵向线路的交汇站下车。

输出格式:

输出文件只有一行,即 \(Serenade\) 在合理选择线路的情况下,回家所需要的时间。如果 \(Serenade\) 无法在不出站换乘的情况下回家,请输出\(-1\)。

输入输出样例

输入样例#1:

2 1
1 2
1 1 2 2

输出样例#1:

5

输入样例#2:

6 9
2 1
2 5
3 2
4 4
5 2
5 6
6 1
6 3
6 4
1 1 4 6

输出样例#2:

27

输入样例#3:

6 10
2 1
2 5
3 2
4 4
5 2
5 6
6 1
6 3
6 4
6 6
1 1 4 6

输出样例#3:

26

说明

对于 \(30\%\)的数据,\(n\le 50,m\le 1000\);

对于 \(60\%\)的数据,\(n\le 500,m\le 2000\);

对于 \(100\%\)的数据,\(n\le 20000,m\le 100000\);

思路:

裸的分层最短路,对于这个题目来说,层与层之间的权值为\(1\)。

而且看数据范围,\(n\)这么大的一个范围,肯定不能\(n^2\)存图了,那么我们就枚举每个中转点(换乘点),横纵分别求两个中转点之间的距离,然后存下来,每层起点和起点的映射及终点和终点的映射都要是0,然后直接上堆优化dijkstra,这个题就做完了。

分层最短路需要注意的问题:

1、数组的大小,这个很重要。

2、确定每层之间的权值是多少。

3、考虑如何建边。

注意了这三个问题之后,分层最短路就跟裸的最短路没什么区别了……

于是我们开开心心的来看代码(代码就不解释了,有了思路就能看懂):

#include<cstdio>
#include<algorithm>
#include<queue>
#include<cctype>
#include<cstring>
#define maxn 200001
using namespace std;
int num,n,m,head[800001],dis[800001];
inline int qread() {
char c=getchar();int num=0,f=1;
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) num=num*10+c-'0';return num*f;
}
struct edge {
int v,w,nxt;
}e[800001];
struct node {
int x,y;
bool operator < (const node &a) const {return y>a.y;}
};
struct Edge {
int x,y,id;
}zrj[maxn];
bool cmp1(Edge a,Edge b){if(a.x==b.x)return a.y<b.y;return a.x<b.x;}
bool cmp2(Edge a,Edge b){if(a.y==b.y)return a.x<b.x;return a.y<b.y;}
inline void ct(int u, int v, int w) {
e[++num].v=v;
e[num].w=w;
e[num].nxt=head[u];
head[u]=num;
}
priority_queue<node>q;
inline void dijkstra() {
memset(dis,0x3f,sizeof(dis));
dis[m+1]=0;q.push((node){m+1,0});
while(!q.empty()) {
int u=q.top().x,d=q.top().y;
q.pop();
if(d!=dis[u]) continue;
for(int i=head[u];i;i=e[i].nxt) {
int v=e[i].v;
if(dis[v]>dis[u]+e[i].w) {
dis[v]=dis[u]+e[i].w;
q.push((node){v,dis[v]});
}
}
}
}
int main() {
n=qread(),m=qread();
for(int i=1;i<=m+2;++i) zrj[i].x=qread(),zrj[i].y=qread(),zrj[i].id=i;
sort(zrj+1,zrj+m+3,cmp1);
for(int i=1;i<m+2;++i)
{if(zrj[i].x==zrj[i+1].x) ct(zrj[i].id,zrj[i+1].id,(zrj[i+1].y-zrj[i].y)*2),ct(zrj[i+1].id,zrj[i].id,(zrj[i+1].y-zrj[i].y)*2);}
sort(zrj+1,zrj+m+3,cmp2);
for(int i=1;i<m+2;++i)
{if(zrj[i].y==zrj[i+1].y) ct(zrj[i].id+m+2,zrj[i+1].id+m+2,(zrj[i+1].x-zrj[i].x)*2),ct(zrj[i+1].id+m+2,zrj[i].id+m+2,(zrj[i+1].x-zrj[i].x)*2);}
for(int i=1;i<=m;++i) ct(i,i+m+2,1),ct(i+m+2,i,1);
ct(m+1,m*2+3,0),ct(m*2+3,m+1,0);ct(m+2,m*2+4,0),ct(m*2+4,m+2,0);
dijkstra();
if(dis[m+2]>1e9) printf("-1\n");
else printf("%d\n",dis[m+2]);
return 0;
}

希望这篇题解可以对大家了解分层最短路有些帮助。

洛谷P3831 回家的路的更多相关文章

  1. 洛谷 P2802 回家

    题目链接 https://www.luogu.org/problemnew/show/P2802 题目描述 小H在一个划分成了n*m个方格的长方形封锁线上. 每次他能向上下左右四个方向移动一格(当然小 ...

  2. 洛谷 P3819 松江1843路

    题目描述 涞坊路是一条长L米的道路,道路上的坐标范围从0到L,路上有N座房子,第i座房子建在坐标为x[i]的地方,其中住了r[i]人. 松江1843路公交车要在这条路上建一个公交站,市政府希望让最多的 ...

  3. 洛谷P1529 回家 Bessie Come Home

    P1529 回家 Bessie Come Home 题目描述 现在是晚餐时间,而母牛们在外面分散的牧场中. 农民约翰按响了电铃,所以她们开始向谷仓走去. 你的工作是要指出哪只母牛会最先到达谷仓(在给出 ...

  4. 洛谷——P1529 回家 Bessie Come Home

    P1529 回家 Bessie Come Home 题目描述 现在是晚餐时间,而母牛们在外面分散的牧场中. 农民约翰按响了电铃,所以她们开始向谷仓走去. 你的工作是要指出哪只母牛会最先到达谷仓(在给出 ...

  5. 洛谷 P1529 回家 Bessie Come Home

    P1529 回家 Bessie Come Home 题目描述 现在是晚餐时间,而母牛们在外面分散的牧场中. 农民约翰按响了电铃,所以她们开始向谷仓走去. 你的工作是要指出哪只母牛会最先到达谷仓(在给出 ...

  6. 洛谷 P1529 回家 Bessie Come Home Label:Dijkstra最短路 && 乱搞

    题目描述 现在是晚餐时间,而母牛们在外面分散的牧场中. 农民约翰按响了电铃,所以她们开始向谷仓走去. 你的工作是要指出哪只母牛会最先到达谷仓(在给出的测试数据中,总会有且只有一只最快的母牛). 在挤奶 ...

  7. 洛谷P3819 松江1843路

    P3819 松江1843路 题目描述 涞坊路是一条长L米的道路,道路上的坐标范围从0到L,路上有N座房子,第i座房子建在坐标为x[i]的地方,其中住了r[i]人. 松江1843路公交车要在这条路上建一 ...

  8. 洛谷P1556 幸福的路

    P1556 幸福的路 题目描述 每天,John都要为了农场里N(1≤N≤10)头牛的健康和幸福四处奔波. 每头牛的位置可以描述为一个二维坐标,John从坐标原点(0,0)出发.为了使路径更有趣,Joh ...

  9. 洛谷P2939 [USACO09FEB]改造路Revamping Trails

    题意翻译 约翰一共有\(N\))个牧场.由\(M\)条布满尘埃的小径连接.小径可 以双向通行.每天早上约翰从牧场\(1\)出发到牧场\(N\)去给奶牛检查身体. 通过每条小径都需要消耗一定的时间.约翰 ...

随机推荐

  1. POJ 2348 Euclid Game (模拟题)

    Euclid's Game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7942   Accepted: 3227 Des ...

  2. 吴恩达机器学习笔记(十二) —— Application Example: Photo OCR(完)

    主要内容: 一.Photo OCR 二.Getting lots of data:artificial data synthesis 三.Ceiling analysis 一.Photo OCR Ph ...

  3. 通道(Channel)的原理获取

    通道表示打开到 IO 设备(例如:文件.套接字)的连接.若需要使用 NIO 系统,需要获取用于连接 IO 设备的通道以及用于容纳数据的缓冲区.然后操作缓冲区,对数据进行处理.Channel 负责传输, ...

  4. (5)表单Action后台验证

    /day31/src/cn/itcast/web/struts2/user/UserAction.java package cn.itcast.web.struts2.user; import com ...

  5. BZOJ 1191 [HNOI2006]超级英雄Hero:二分图匹配 匈牙利算法

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1191 题意: 有m道题,每答对一题才能接着回答下一个问题. 你一道题都不会,但是你有n个“ ...

  6. CentOS Wifi Connection

    方法一: http://wiki.centos.org/HowTos/Laptops/WpaSupplicant http://www.cnblogs.com/tanghuimin0713/p/343 ...

  7. 分享知识-快乐自己:2017IDEA破解教程

    首先 修改host文件: 文件路径:C:\Windows\System32\drivers\etc\hosts 修改:将“0.0.0.0 account.jetbrains.com”追加到hosts文 ...

  8. 开机时遇到grub rescue无法进入系统的解决方法

    装双系统(win10和elementary os),elementary os是ubuntu的一个分支.在win10中合并了一块空白磁盘分区,再开机的时候出问题了. 遇到filesystem unkn ...

  9. Codeforces 762B USB vs. PS/2 贪心

    Codeforces 762B 题目大意: 有a台只有USB接口的电脑,b台PS/2接口的电脑,c台两种接口都有的电脑.每台电脑只用装一个鼠标.给出n个鼠标及其费用,每个鼠标只能使用一遍.在最大化有鼠 ...

  10. 京东SDK模板卡盘效果实现代码

    最近在做京东模板,因为是最新平台,好多功能都需要摸索,俺技术一般,摸索出一个简易的卡盘功能   ——————使用的是分类推荐模块哦! 本着共享的精神,俺将代码放到这儿了,各人请自便.(代码还不够完善, ...