问题 A: 现代豪宅

时间限制: 1 Sec  内存限制: 256 MB

题面


题目描述

(题目译自 $JOI 2013 Final T3$「現代的な屋敷」)

你在某个很大的豪宅里迷路了。这个豪宅由东西方向$M$列,南北方向$N$行的正方形房间组成。

从西面开始第$x$列,从南面开始第y行的房间用$(x,y)$表示。

相邻的两个房间之间都有一扇门。对于每扇门,门关上表示不可通行,门打开表示可以通行。

当门打开时,从门一边的房间走到另一边的房间需要$1$分钟。

另外,一些房间中有一个开关,如果连续$1$分钟按住这个开关,那么所有关上的门会打开,所有打开的门会关闭。

现在,连接东西两个房间的门全都是关上的,连接南北两个房间的门全都是打开的。

你现在在房间$(1,1)$,要在最短的时间内移动到房间$(M,N)$

任务

给出豪宅的大小M、N,以及存在开关的K个房间的位置$(x_1,y_1)、(x_2,y_2)、(x_k,y_k)$

开始时,连接东西两个房间的门全都是关上的,连接南北的两个房间全都是打开的。

请编写程序求出从房间$(1,1)$到达房间$(M,N)$的最短时间。不能到达时,请输出$-1$

输入格式

输入标准如下:

第一行为三个以空格分开的整数$M、N、K$。

$M$表示东西方向上房间的个数,$N$表示南北方向上房间的个数,$K$表示存在开关的房间的个数。

接下来$K$行中的第$i$行为两个以空格分开的整数。

表示房间$(x_i,y_i)$中存在开关。这个二元组间彼此相异。

输出格式

输出一行一个整数:表示移动所需的最短时间。如果不能到达房间$(M,N)$则输出$-1$。

样例输入

3 2 1

1 2

样例输出

4

数据范围

$2<=M,N<=10^5,1<=K<=2*10^5,1<=X_i<=M,1<=Y_i<=N$

题解


考虑拆点。

将每一个点拆成横纵两个点,横点和纵点之间连边,边权为1。(门状态转换的代价)

对同行的$(X_i,Y_i)$的横点连边,边权为距离。对同列的$(X_i,Y_i)$的纵点连边,边权为距离。

跑堆优化dijkstra即可。

(JOI的代码难度相比NOIP几乎没有?/大雾)

(然而我还是调了半个小时/大雾)

#include<bits/stdc++.h>
#define int long long
#define inf 0x3f3f3f3f3f3f3f3f
#define read(A) A=init()
#define rint register int
#define N 3000005
#define M 40000006
using namespace std;
inline int init()
{
int a=,b=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')b=-;ch=getchar();}
while(ch>=''&&ch<=''){a=(a<<)+(a<<)+ch-'';ch=getchar();}
return a*b;
}
int m,n,k,st,en,dist[N],cnt;
int tot,v[M],w[M],nxt[M],first[N];
struct node{int zb,id;}pot[N];
struct node2{
int x,y;
friend bool operator < (node2 A,node2 B){
return A.y>B.y;
}
};
vector <node> hine[N],line[N];
priority_queue <node2> QAQ;
inline bool cmp(node A,node B){return A.zb<B.zb;}
inline void add(int uu,int vv,int ww)
{
v[++tot]=vv,w[tot]=ww;
nxt[tot]=first[uu];first[uu]=tot;
}
inline void dijkstra()
{
for(rint i=;i<=*k+;i++)dist[i]=inf;
dist[st]=;QAQ.push((node2){st,dist[st]});
while(!QAQ.empty())
{
int x=QAQ.top().x,y=QAQ.top().y;
QAQ.pop();
if(y>dist[x]) continue;
for(rint i=first[x];i!=-;i=nxt[i])
{
int to=v[i],val=w[i];
if(dist[to]>dist[x]+val)
{
dist[to]=dist[x]+val;
QAQ.push((node2){to,dist[to]});
}
}
}
}
signed main()
{
memset(first,-,sizeof(first));
read(m),read(n),read(k);en=*k+;
for(rint i=,xi,yi;i<=k;++i)
{
read(xi),read(yi);++cnt;
line[xi].push_back((node){yi,cnt+k});
hine[yi].push_back((node){xi,cnt});
}
for(rint i=;i<=n;++i)
{
sort(hine[i].begin(),hine[i].end(),cmp);
for(rint j=;j<hine[i].size();++j)
{
add(hine[i][j-].id,hine[i][j].id,hine[i][j].zb-hine[i][j-].zb),
add(hine[i][j].id,hine[i][j-].id,hine[i][j].zb-hine[i][j-].zb);
}
}
if(hine[n].size())
{
int zhi=hine[n].size()-;
add(en,hine[n][zhi].id,m-hine[n][zhi].zb);
add(hine[n][zhi].id,en,m-hine[n][zhi].zb);
}
for(rint i=;i<=m;++i)
{
sort(line[i].begin(),line[i].end(),cmp);
for(rint j=;j<line[i].size();++j)
{
add(line[i][j-].id,line[i][j].id,line[i][j].zb-line[i][j-].zb),
add(line[i][j].id,line[i][j-].id,line[i][j].zb-line[i][j-].zb);
}
}
if(line[m].size())
{
int zhi=line[m].size()-;
add(en,line[m][zhi].id,n-line[m][zhi].zb);
add(line[m][zhi].id,en,n-line[m][zhi].zb);
}
if(line[].size())
{
add(st,line[][].id,line[][].zb-);
add(line[][].id,st,line[][].zb-);
}
for(rint i=;i<=k;++i)add(i,i+k,),add(i+k,i,);
dijkstra();
(dist[en]>=inf)?puts("-1"):printf("%lld\n",dist[en]);
return ;
}

「题解」:[loj2763][JOI2013]现代豪宅的更多相关文章

  1. 「题解」「美团 CodeM 资格赛」跳格子

    目录 「题解」「美团 CodeM 资格赛」跳格子 题目描述 考场思路 思路分析及正解代码 「题解」「美团 CodeM 资格赛」跳格子 今天真的考自闭了... \(T1\) 花了 \(2h\) 都没有搞 ...

  2. 「题解」「HNOI2013」切糕

    文章目录 「题解」「HNOI2013」切糕 题目描述 思路分析及代码 题目分析 题解及代码 「题解」「HNOI2013」切糕 题目描述 点这里 思路分析及代码 题目分析 这道题的题目可以说得上是史上最 ...

  3. 「题解」JOIOI 王国

    「题解」JOIOI 王国 题目描述 考场思考 正解 题目描述 点这里 考场思考 因为时间不太够了,直接一上来就着手暴力.但是本人太菜,居然暴力爆 000 ,然后当场自闭- 一气之下,发现对 60pts ...

  4. 「题解」:$Six$

    问题 A: Six 时间限制: 1 Sec  内存限制: 512 MB 题面 题面谢绝公开. 题解 来写一篇正经的题解. 每一个数对于答案的贡献与数本身无关,只与它包含了哪几个质因数有关. 所以考虑二 ...

  5. 「题解」:$Smooth$

    问题 A: Smooth 时间限制: 1 Sec  内存限制: 512 MB 题面 题面谢绝公开. 题解 维护一个队列,开15个指针,对应前15个素数. 对于每一次添加数字,暴扫15个指针,将指针对应 ...

  6. 「题解」:Kill

    问题 A: Kill 时间限制: 1 Sec  内存限制: 256 MB 题面 题面谢绝公开. 题解 80%算法 赛时并没有想到正解,而是选择了另一种正确性较对的贪心验证. 对于每一个怪,我们定义它的 ...

  7. 「题解」:y

    问题 B: y 时间限制: 1 Sec  内存限制: 256 MB 题面 题面谢绝公开. 题解 考虑双向搜索. 定义$cal_{i,j,k}$表示当前已经搜索状态中是否存在长度为i,终点为j,搜索过边 ...

  8. 「题解」:x

    问题 A: x 时间限制: 1 Sec  内存限制: 256 MB 题面 题面谢绝公开. 题解 赛时想到了正解并且对拍了很久.对拍没挂,但是评测姬表示我w0了……一脸懵逼. 不难证明,如果对于两个数字 ...

  9. 「题解」:07.16NOIP模拟T1:礼物

    问题 A: 礼物 时间限制: 1 Sec  内存限制: 256 MB 题面 题目描述 夏川的生日就要到了.作为夏川形式上的男朋友,季堂打算给夏川买一些生 日礼物. 商店里一共有种礼物.夏川每得到一种礼 ...

随机推荐

  1. Red5流媒体服务器开发

    Red5流媒体服务器开发总结 Red5 是 支持Windows,Linux等多平台的RTMP流媒体服务器,最早属于谷歌下的开源项目,先已移植到Github,地址为https://github.com/ ...

  2. “使用Adobe Reader XI打开PDF文件,左侧无法显示导航列表”解决方法

    在Word中将文档另存为PDF格式之后,再使用Adobe Reader XI打开,没有左侧导航列表: 解决步骤: 1.在word另存为时,在另存为对话框中,点击如下图所示的“选项” 2.在弹出的对话框 ...

  3. 明年将制定个人信息保护法 网站部署https迫在眉睫

    12月20日,全国人大常委会法工委举行第三次记者会.全国人大常委会法工委发言人岳仲明表示,中国明年将制定个人信息保护法.数据安全法等. 数据泄露为何频频出现 你是否经常接到骚扰电话?推销.诈骗等等均有 ...

  4. 改变this 指向的3种方法

    1.在函数内部声明一个that,然后将this赋值给that, var that=this; 最后用that 代替this使用 <!DOCTYPE html> <html lang= ...

  5. ES6 Sybol属性

    Symbol: 概念:ES6中的添加了一种原始数据类型symbol(已有的原始数据类型:String, Number, boolean, null, undefined, 对象) 特点: 1.Symb ...

  6. leetcode -有效的字母异位词 python&C++

    C++解题代码: class Solutiion { public: bool isAnagram(string s, string t) { ](); int n = s.length(); int ...

  7. JAVA javac

    { 用法: javac <options> <source files>其中, 可能的选项包括:  -g                         生成所有调试信息  - ...

  8. Java 并发总结(三)

    锁优化及注意事项 有助于提高锁的性能 减小所持有时间:例如不要对方法直接加锁,而是在方法中对具体访问临界资源的代码加锁 减小锁粒度:如ConcurrentHashMap 用读写锁代替独占锁 锁分离:如 ...

  9. ionic-CSS:ionic Toggle(切换开关)

    ylbtech-ionic-CSS:ionic Toggle(切换开关) 1.返回顶部 1. ionic Toggle(切换开关) 切换开关类似与 HTML 的 checkbox 标签,但它更易于在移 ...

  10. AsyncAwait

    using System; using System.Diagnostics; using System.Threading; using System.Threading.Tasks; namesp ...