考虑从起点到终点的过程,一定是先将空格子移到指定格子旁边,和指定格子交换,再移到下一个指定格子要到的地方,再交换,如此反复。

于是问题分为两个部分:

1.给定两个曼哈顿距离为2的格子求最短路,BFS即可。

2.根据1的结果决定从起点到终点的路径,使用SPFA求解。

其中,第一个问题空格子显然不能经过指定格子,BFS过程中需要特判。第二个问题的状态为(x,y,k),表示当前指定格子在(x,y),空格子在它的哪个方向(1<=k<=4)。

 #include<cstdio>
#include<cstring>
#include<algorithm>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
using namespace std; const int N=,inf=1e9;
const int dx[]={-,,,},dy[]={,,-,};
bool inq[<<],mp[N][N];
int n,m,Q,ex,ey,sx,sy,tx,ty,d[<<],dis[N][N],cost[<<];
struct P{ int x,y; }q[<<];
struct S{ int x,y,dir; }q2[<<]; int F(int x,int y,int a,int b){ return x<< | y<< | a<< | b; }
int F(int x,int y,int k){ return x<< | y<< | k; } void bfs(int x0,int y0,int x1,int y1){
memset(dis,-,sizeof(dis));
mp[x1][y1]=; int st=,ed=,tot=; q[]=(P){x0,y0}; dis[x0][y0]=;
while (st<ed){
int x=q[++st].x,y=q[st].y;
if (abs(x-x1)+abs(y-y1)==)
if (--tot==) break;
rep(k,,){
int x2=x+dx[k],y2=y+dy[k];
if (mp[x2][y2] && dis[x2][y2]==-)
dis[x2][y2]=dis[x][y]+,q[++ed]=(P){x2,y2};
}
}
mp[x1][y1]=;
} void init(){
rep(i,,n) rep(j,,m) if (mp[i][j])
rep(p,,){
int x1=i+dx[p],y1=j+dy[p];
if (!mp[x1][y1]) continue;
bfs(i,j,x1,y1);
rep(q,,){
int x2=x1+dx[q],y2=y1+dy[q];
if (~dis[x2][y2]) cost[F(x1,y1,p^,q)]=dis[x2][y2]+;
}
}
} int spfa(){
int st=,ed=;
memset(d,0x3f,sizeof(d));
bfs(ex,ey,sx,sy);
rep(k,,){
int x1=sx+dx[k],y1=sy+dy[k];
if (dis[x1][y1]==-) continue;
q2[++ed]=(S){sx,sy,k}; d[F(sx,sy,k)]=dis[x1][y1]; inq[F(sx,sy,k)]=;
}
while (st<ed){
int x=q2[++st].x,y=q2[st].y,dir=q2[st].dir,u=F(x,y,dir); inq[u]=;
rep(k,,){
int x1=x+dx[k],y1=y+dy[k],c=cost[F(x,y,dir,k)],v=F(x1,y1,k^);
if (mp[x1][y1] && c && d[v]>d[u]+c){
d[v]=d[u]+c; if (!inq[v]) q2[++ed]=(S){x1,y1,k^},inq[v]=;
}
}
}
int ans=inf;
rep(k,,) ans=min(ans,d[F(tx,ty,k)]);
return ans==inf ? - : ans;
} int main(){
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
scanf("%d%d%d",&n,&m,&Q);
rep(i,,n) rep(j,,m) scanf("%d",&mp[i][j]);
init();
while (Q--){
scanf("%d%d%d%d%d%d",&ex,&ey,&sx,&sy,&tx,&ty);
if (sx==tx && sy==ty) { puts(""); continue; }
printf("%d\n",spfa());
}
return ;
}

[Luogu1979][NOIP2013]华容道(BFS+SPFA)的更多相关文章

  1. JZYZOJ1442 [noip2013]华容道 bfs 最短路 剪枝

    http://172.20.6.3/Problem_Show.asp?id=1442 想到最短路的简直神了,如果我写我大概只能写一个30分的bfs. 从数据范围可以看出思路是bfs剪枝,但这里的剪枝是 ...

  2. [NOIP2013]华容道 题解(搜索)

    [NOIP2013]华容道 [题目描述] 这道题根据小时候玩华容道不靠谱的经验还以为是并查集,果断扑街.考后想想也是,数据这么小一定有他的道理. 首先由于是最小步数,所以BFS没跑了.那么我们大可把这 ...

  3. [NOIP2013]华容道 题解

    [NOIP2013]华容道 首先是一种比较显然的做法. 整个棋盘,除了起点,终点和空格,其他的方块是等价的. 对于终点,它始终不会变化,如果搜到终点结束搜索即可,所以我们不需要考虑终点. 所以需要考虑 ...

  4. LOJ2613 NOIP2013 华容道 【最短路】*

    LOJ2613 NOIP2013 华容道 LINK 这是个好题,具体题意比较麻烦可以直接看LINK中的链接 然后考虑我们可能的移动方式 首先我们需要把白块移动到需要移动块S的附近(附近四格) 然后我们 ...

  5. codevs 3290 华容道(SPFA+bfs)

    codevs 3290华容道 3290 华容道 2013年NOIP全国联赛提高组 时间限制: 1 s  空间限制: 128000 KB 题目描述 Description 小 B 最近迷上了华容道,可是 ...

  6. NOIP2013 提高组day2 3 华容道 BFS

    描述 小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面,华容道是否根本就无法完成,如果能完成,最少需要多少时间. 小 B 玩的华容道与经典的 ...

  7. NOIP2013 华容道 (棋盘建图+spfa最短路)

    #include <cstdio> #include <algorithm> #include <cstring> #include <queue> # ...

  8. bzoj P1979 华容道【bfs+spfa】

    调死我了-- 首先观察移动方式,需要移动的格子每次移动到相邻格子,一定是先把空白格子挪过去,所以我们得到一种做法,就是bfs预处理出每一个格子的四联通格子之间的空白格子移动距离建边,注意这个移动是不能 ...

  9. NOIP2013华容道(BFS+乱搞)

    n<=30 * m<=30 的地图上,0表示墙壁,1表示可以放箱子的空地.q<=500次询问,每次问:当空地上唯一没有放箱子的空格子在(ex,ey)时,把位于(sx,sy)的箱子移动 ...

随机推荐

  1. Bzoj3224 / Tyvj 1728 普通替罪羊树

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 12015  Solved: 5136 Description 您需要写一种数据结构(可参考题目标题), ...

  2. 基数排序——尚未补完的坑QAQ

    基数排序复杂度是(n+b)logn/logb 我们找一个基数 每次处理一部分位 从低位到高位处理 t是出现次数 s是这个桶管辖的起点 然后就可以写了 不过我这里是指针版的 有点难看 #include& ...

  3. 15、简述MySQL的执行计划?

    具体的Mysql的执行计划,请参考下面的链接: MySQL_执行计划详细说明

  4. eCharts 多个图表自适应窗口大小

    单个图表自适应页面窗口只需要在创建图表节点后面添加一句代码就可以了: window.onresize = myChart.resize; 多图表要自适应页面,创建图表节点后面添加事件,并在事件函数里面 ...

  5. a标签的嵌套

    1.a标签的嵌套 a标签不能嵌套,若a标签中嵌套了a标签,浏览器会自动添加结束符号,故不能嵌套 2.例子 编辑器中的代码 <a href="#">外层a标签<a ...

  6. Java基础 变量和数据类型及相关操作

    Java基本语法: 1):Java语言严格区分大小写,好比main和Main是完全不同的概念. 2):一个Java源文件里可以定义多个Java类,但其中最多只能有一个类被定义成public类.若源文件 ...

  7. linux编程之信号

    信号(signal)机制是UNIX系统中最为古老的进程之间的通信机制,它用在一个或多个进程之间传递异步信号,信号可以由各种异步事件产生,如: 键盘中断等等,在Linux 的shell 中,也可以使用信 ...

  8. Laravel 项目登录报错:The MAC is invalid.

    在 Laravel 项目完成部署到服务器.数据库导入成功后 后台登录报错: 原因是 Laravel 的 APP_KEY 和 encrypt() 函数加密的问题.(encrypt() 是 Laravel ...

  9. Deep Learning基础--参数优化方法

    1. 深度学习流程简介 1)一次性设置(One time setup)          -激活函数(Activation functions) - 数据预处理(Data Preprocessing) ...

  10. git subtree:无缝管理通用子项目

    移动互联网的爆发以及响应式页面的尴尬症,开发web和mobile项目成为了标配,当然实际情况下,会有更多的项目. 多项目开发对于前端来说是个很大的挑战✦ 重复,重复的前端架构,重复的前端依赖,重复的工 ...