[Luogu1979][NOIP2013]华容道(BFS+SPFA)
考虑从起点到终点的过程,一定是先将空格子移到指定格子旁边,和指定格子交换,再移到下一个指定格子要到的地方,再交换,如此反复。
于是问题分为两个部分:
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)的更多相关文章
- JZYZOJ1442 [noip2013]华容道 bfs 最短路 剪枝
http://172.20.6.3/Problem_Show.asp?id=1442 想到最短路的简直神了,如果我写我大概只能写一个30分的bfs. 从数据范围可以看出思路是bfs剪枝,但这里的剪枝是 ...
- [NOIP2013]华容道 题解(搜索)
[NOIP2013]华容道 [题目描述] 这道题根据小时候玩华容道不靠谱的经验还以为是并查集,果断扑街.考后想想也是,数据这么小一定有他的道理. 首先由于是最小步数,所以BFS没跑了.那么我们大可把这 ...
- [NOIP2013]华容道 题解
[NOIP2013]华容道 首先是一种比较显然的做法. 整个棋盘,除了起点,终点和空格,其他的方块是等价的. 对于终点,它始终不会变化,如果搜到终点结束搜索即可,所以我们不需要考虑终点. 所以需要考虑 ...
- LOJ2613 NOIP2013 华容道 【最短路】*
LOJ2613 NOIP2013 华容道 LINK 这是个好题,具体题意比较麻烦可以直接看LINK中的链接 然后考虑我们可能的移动方式 首先我们需要把白块移动到需要移动块S的附近(附近四格) 然后我们 ...
- codevs 3290 华容道(SPFA+bfs)
codevs 3290华容道 3290 华容道 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description 小 B 最近迷上了华容道,可是 ...
- NOIP2013 提高组day2 3 华容道 BFS
描述 小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面,华容道是否根本就无法完成,如果能完成,最少需要多少时间. 小 B 玩的华容道与经典的 ...
- NOIP2013 华容道 (棋盘建图+spfa最短路)
#include <cstdio> #include <algorithm> #include <cstring> #include <queue> # ...
- bzoj P1979 华容道【bfs+spfa】
调死我了-- 首先观察移动方式,需要移动的格子每次移动到相邻格子,一定是先把空白格子挪过去,所以我们得到一种做法,就是bfs预处理出每一个格子的四联通格子之间的空白格子移动距离建边,注意这个移动是不能 ...
- NOIP2013华容道(BFS+乱搞)
n<=30 * m<=30 的地图上,0表示墙壁,1表示可以放箱子的空地.q<=500次询问,每次问:当空地上唯一没有放箱子的空格子在(ex,ey)时,把位于(sx,sy)的箱子移动 ...
随机推荐
- 【NOIP】提高组2015 跳石头
[算法]二分查找 [题解]最小值最大化问题. 从1..l内二分枚举答案,将每个答案最少移开的石头数与最大移开数m比较. 精简写法学自:https://vijos.org/p/1981/solution ...
- [bzoj4569][SCOI2016]萌萌哒-并查集+倍增
Brief Description 一个长度为n的大数,用S1S2S3...Sn表示,其中Si表示数的第i位,S1是数的最高位,告诉你一些限制条件,每个条 件表示为四个数,l1,r1,l2,r2,即两 ...
- web服务器和数据库服务器不在一台机器上
把localhost改成数据库所在的IP就行了. $link=mysql_connect( "202.195.246.202 ", "root ", " ...
- Vue组件-动态组件
动态组件 通过使用保留的 <component> 元素,动态地绑定到它的 is 特性,可以让多个组件使用同一个挂载点,并动态切换: <div id="app6"& ...
- Vue基本指令
模板对象 vue指令 一:模板对象 <!DOCTYPE html> <html lang="en"> <head> <meta chars ...
- FAN54015 充電電流 軟硬體設定
Ex1: Vrsense 選 37.4 mV --- 在第二張圖 Rsense 選 50 mΩ --- 在第三張圖 37.4 / 50 = 748 mA Ex2: Vrsense 選 44.2 mV ...
- 【UOJ224】短路
具体可以看UOJmyy的blog,orz 就是一个贪心. #include<bits/stdc++.h> typedef long long ll; using namespace std ...
- Xcode7 iOS9.0 的真机调试
Xcode7的真机调试: 1.Xcode偏好 -> 账号 -> 增加 Apple ID ->显示 free 2.Target 运行 iOS 版本号 3.修正 Team 项 选择 ...
- 动画基础--基于Core Animation(3)
参考:https://zsisme.gitbooks.io/ios-/content/ 前面的文章动画基础--基于Core Animation(1),动画基础--基于Core Animation(2) ...
- 虚拟机 VMware Workstation12 安装Ubuntu系统
Ubuntu 系统是一款优秀的.基于GNU/Linux 的平台的桌面系统. 当然,目前为止很多应用程序还完全不能允许运行在 Ubuntu 系统上,而且 Ubuntu 的界面.使用方法会让大部分Wind ...