问题 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. Asp.net Core + Log4net + ELK 搭建日志中心

    原文:Asp.net Core + Log4net + ELK 搭建日志中心 Docker中一键安装ELK 对于这种工具类的东西,第一步就直接到docker的hub中查找了,很幸运,不仅有Elasti ...

  2. GetModuleHandleW 分析

    首先查询MSDN,可以清楚地看到 位于kernel32 dll 里面. 有目标就好办,找到这个dll,然后,开工,进入IDA. 跳啊 就到下面那块了. 遗憾的是...显然不是这里阿,实际上下一块调用的 ...

  3. java中equse和==做比较记录(转)

    String使用的equals方法和==的区别 equals方法和==的区别   首先大家知道,String既可以作为一个对象来使用,又可以作为一个基本类型来使用.这里指的作为一个基本类型来使用只是指 ...

  4. 【FJWC2018】最大真因数

    题面 Description 一个合数的真因数是指这个数不包括其本身的所有因数, 例如 6 的正因数有1, 2, 3, 6,其中真因数有 1, 2, 3. 一个合数的最大真因数则是这个数的所有真因数中 ...

  5. lombok @Builder实现原理

    public class Person { private Person(Builder builder) { name = builder.name; age = builder.age; } pr ...

  6. leetcood学习笔记-437-路径总和③**

    题目描述: 方法一:栈 class Solution(object): def pathSum(self, root, sum): """ :type root: Tre ...

  7. PHP获取远程客户端真实IP的办法!

    (1).REMOTE_ADDR:浏览当前页面的用户计算机的ip地址 (2).HTTP_X_FORWARDED_FOR: 浏览当前页面的用户计算机的网关 (3).HTTP_CLIENT_IP:客户端的i ...

  8. 区别 |DCL |DDL |DML |DQL

    DCL(Data Control Language)数据控制语言: 用来设置或更改数据库用户或角色权限的语句,包括(grant,deny,revoke等)语句.这个比较少用到. 对于大多数人,在公司一 ...

  9. 我们能从java的HelloWorld学到什么?

    这是每个Java程序员都知道的.虽然简单,但是从一个简单的问题可以引入更深的思考.在这篇文章中,我们将讨论这个简单的程序.如果能更多的帮到你,请留下宝贵的意见. HelloWorld.java pub ...

  10. js判断是否为手机端访问

    随着移动端越来越重要,pc和移动端网站后台系统可能是同一个,登录或者某个特定时期需要根据不同访问来源,跳转不同页面或者做不同的处理: 这时我们就需要js的 navigator 对象: 我们先了解一下n ...