loj2613 「NOIP2013」华容道[最短路]
感觉和以前做过的一个推箱子很像,都是可以用bfs解决的,而且都是手玩出结论。
因为起始棋子肯定是要和空格交换的,所以第一件事是先把空格移到棋子旁边。然后讨论怎么设计搜索状态。由于和推箱子实在太像了,所以直接借鉴,发现空格总是要贴着棋子走的要不然就是换个贴的方向继续走(这里的走就是指交换)。于是绑定两者,设计状态$f_{i,j,dir}$表示在棋子在某个格子,空格在上下左右四方位时候的最小移动次数。显然可以暴力bfs跑,但是这样没有经过优化,效率不高,实际上只要把它改的像最短路算法一点就行了,比如套个dijkstra,把每种状态和他可以推到的下一步状态(分为交换,或者空格跑到另一侧,这个的步数可以提前预处理)之间连边,边权即步数,这样建个图之后就是最短路了,起点有4个,终点有4个,$O(Qn^2\text{log}n^2)$,避免了bfs庞大的搜索树。
然后注意一个很容易忽略的细节。。我第一发就是这么挂掉的。。起点和终点在同一个位置要特判,不然会加上空格到起点的距离然后跪好多点。
code可能是我有史以来写过的最丑的,一堆循环展开。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define dbg(x) cerr << #x << " = " << x <<endl
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,):;}
template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,):;}
template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
template<typename T>inline T read(T&x){
x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
}
const int N=+,INF=0x3f3f3f3f;
int mp[N][N],f[N][N][][],id[N][N][],cnt;
int n,m,Q,hx,hy,sx,sy,tx,ty;
int qx[],qy[],dis[N][N],l,r;
inline void bfs_step(int x,int y){
memset(dis,0x3f,sizeof dis);qx[l=r=]=x,qy[]=y,dis[x][y]=;
while(l<=r){
int i=qx[l],j=qy[l++];
if(!mp[i-][j]&&MIN(dis[i-][j],dis[i][j]+))qx[++r]=i-,qy[r]=j;
if(!mp[i+][j]&&MIN(dis[i+][j],dis[i][j]+))qx[++r]=i+,qy[r]=j;
if(!mp[i][j-]&&MIN(dis[i][j-],dis[i][j]+))qx[++r]=i,qy[r]=j-;
if(!mp[i][j+]&&MIN(dis[i][j+],dis[i][j]+))qx[++r]=i,qy[r]=j+;
}
}
struct thxorz{int to,nxt,w;}G[];
int Head[],tot;
inline void Addedge(int x,int y,int z){
G[++tot].to=y,G[tot].nxt=Head[x],Head[x]=tot,G[tot].w=z;
G[++tot].to=x,G[tot].nxt=Head[y],Head[y]=tot,G[tot].w=z;
}
int dist[];
priority_queue<pii,vector<pii>,greater<pii> > q;
#define y G[j].to
inline void dij(int xx,int yy){
memset(dist,0x3f,sizeof dist);
if(id[xx][yy][])q.push(make_pair(dist[id[xx][yy][]]=dis[xx-][yy],id[xx][yy][]));
if(id[xx][yy][])q.push(make_pair(dist[id[xx][yy][]]=dis[xx][yy+],id[xx][yy][]));
if(id[xx][yy][])q.push(make_pair(dist[id[xx][yy][]]=dis[xx+][yy],id[xx][yy][]));
if(id[xx][yy][])q.push(make_pair(dist[id[xx][yy][]]=dis[xx][yy-],id[xx][yy][]));
while(!q.empty()){
int x=q.top().second,d=q.top().first;q.pop();
if(dist[x]^d)continue;
for(register int j=Head[x];j;j=G[j].nxt)if(MIN(dist[y],d+G[j].w))q.push(make_pair(dist[y],y));
}
}
#undef y
int main(){//freopen("test.in","r",stdin);freopen("test.ans","w",stdout);
read(n),read(m),read(Q);memset(mp,0x3f,sizeof mp);
for(register int i=;i<=n;++i)for(register int j=;j<=m;++j)read(mp[i][j]),mp[i][j]^=;
for(register int i=;i<=n;++i)for(register int j=;j<=m;++j)if(!mp[i][j]){
mp[i][j]=;
if(!mp[i-][j])bfs_step(i-,j),f[i][j][][]=dis[i][j+],f[i][j][][]=dis[i+][j],f[i][j][][]=dis[i][j-],id[i][j][]=++cnt;
if(!mp[i][j+])bfs_step(i,j+),f[i][j][][]=dis[i-][j],f[i][j][][]=dis[i+][j],f[i][j][][]=dis[i][j-],id[i][j][]=++cnt;
if(!mp[i+][j])bfs_step(i+,j),f[i][j][][]=dis[i-][j],f[i][j][][]=dis[i][j+],f[i][j][][]=dis[i][j-],id[i][j][]=++cnt;
if(!mp[i][j-])bfs_step(i,j-),f[i][j][][]=dis[i-][j],f[i][j][][]=dis[i][j+],f[i][j][][]=dis[i+][j],id[i][j][]=++cnt;
mp[i][j]=;
}
for(register int i=;i<=n;++i)for(register int j=;j<=m;++j)if(!mp[i][j]){
for(register int thx=;thx<;++thx)for(register int orz=;orz<;++orz)
if(orz^thx&&id[i][j][thx]&&id[i][j][orz])Addedge(id[i][j][thx],id[i][j][orz],f[i][j][thx][orz]);
if(id[i][j][])Addedge(id[i][j][],id[i-][j][],);
if(id[i][j][])Addedge(id[i][j][],id[i][j-][],);
}
while(Q--){
read(hx),read(hy),read(sx),read(sy),read(tx),read(ty);
if(sx==tx&&sy==ty){puts("");continue;}
mp[sx][sy]=;bfs_step(hx,hy);mp[sx][sy]=;
dij(sx,sy);
int tmp=_min(dist[id[tx][ty][]],_min(dist[id[tx][ty][]],_min(dist[id[tx][ty][]],dist[id[tx][ty][]])));
printf("%d\n",tmp<INF?tmp:-);
}
return ;
}
总结:棋盘类问题求最小解有常用方法就是最短路建模,注意考虑状态设计有效性,必要时跑分层图。
loj2613 「NOIP2013」华容道[最短路]的更多相关文章
- 「NOIP2013」华容道
传送门 Luogu 解题思路 预支一点东西: 这题其实有着更为思维的图模型,还十分考验码力,不简单啊 这居然是联赛题 讲正解: 显然我们对于一种合法方案,空格子肯定是一直围绕着特定棋子反复横跳的. 所 ...
- 「NOIP2013」「LuoguP1967」货车运输(最大生成树 倍增 LCA
题目描述 AA国有nn座城市,编号从 11到nn,城市之间有 mm 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 qq 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最 ...
- LG1983 「NOIP2013」车站分级 拓扑排序
问题描述 LG1983 题解 考虑建立有向边\((a,b)\),代表\(a\)比\(b\)低级. 于是枚举每一辆车次经过的车站\(x \in [l,r]\),如果不是车辆停靠的车站,则从\(x\)向每 ...
- 「NOIP2013」货车运输
传送门 Luogu 解题思路 首先 \(\text{Kruskal}\) 一下,构造出一棵森林. 并查集还要用来判断连通性. 倍增 \(\text{LCA}\) 的时候顺便维护一下路径最小值即可. 细 ...
- 「bzoj1003」「ZJOI2006」物流运输 最短路+区间dp
「bzoj1003」「ZJOI2006」物流运输---------------------------------------------------------------------------- ...
- 2090. 「ZJOI2016」旅行者 分治,最短路
2090. 「ZJOI2016」旅行者 链接 loj 思路 \((l,mid)(mid+1,r)\).考虑跨过mid的贡献. 假设选的中间那条线的点为gzy,贡献为\(dis(x,gzy)+dis(g ...
- 「BZOJ3694」「FJ2014集训」最短路
「BZOJ3694」「FJ2014集训」最短路 首先树剖没得说了,这里说一下并查集的做法, 对于一条非树边,它会影响的点就只有u(i),v(i)到lca,对于lca-v的路径上所有点x,都可通过1-t ...
- 「luogu4366」最短路
「luogu4366」最短路 传送门 直接连边显然不行,考虑优化. 根据异或的结合律和交换律等优秀性质,我们每次只让当前点向只有一位之别的另一个点连边,然后就直接跑最短路. 注意点数会很多,所以用配对 ...
- 「ZJOI2016」解题报告
「ZJOI2016」解题报告 我大浙的省选题真是超级神仙--这套已经算是比较可做的了. 「ZJOI2016」旅行者 神仙分治题. 对于一个矩形,每次我们从最长边切开,最短边不会超过 \(\sqrt{n ...
随机推荐
- vim中ctrl+z,jobs,fg命令用法
例如:vi test.cctrl + z 将vi 打开的test.c停止并转到后台又打开一个vi buf.cctrl + z 将vi 打开的buf.c停止并转到后台此时通过jobs可以看到任务列表通过 ...
- java集合List解析
作为一个Developer,Java集合类是我们在工作中运用最多的.最频繁的类.相比于数组(Array)来说,集合类的长度可变,更加适合于现代开发需求: Java集合就像一个容器,可以存储任何类型的数 ...
- vue中关于checkbox数据绑定v-model指令说明
vue.js为开发者提供了很多便利的指令,其中v-model用于表单的数据绑定很常见, 下面是最常见的例子: <div id='myApp'> <input type="c ...
- python病毒
介绍 今天碰到一个有趣的python病毒,在这里https://github.com/cranklin/Python-Virus/blob/master/pythonvirus.py#L37 源码 分 ...
- T100——作业action执行其他P作业,后台背景执行完后才能继续操作改作业
范例:如axmt500订单,查询开单占用量: 客制作业cxmp500,通过参数-订单号,查询该订单下的料件,目前有库存量.开单占用量.库存可用量,查询后更新到该订单下的单身对应栏位: 现在axmt50 ...
- golang 客户端
package main import ( "fmt" "io/ioutil" "net/http" ) func main() { fmt ...
- Python库的优雅安装及PyCharm虚拟环境配置
一.安装python库 安装python库有几种方式: 1. 使用pip命令行,如:pip install Pillow 2. 在pycharm中安装 3. 使用Anaconda批量安装常用模块 在使 ...
- mysql解决fail to open file的方法
由于没有安装有mysql的可视化工具,在使用cmd导入sql文件时,使用source 命令时出现 fail to open file的错误,各种查找后使用以下方法解决了: 1.首先进入mysql数据库 ...
- sql lesson21homework
2017-08-15 18:03:17 mysql> show databases;+--------------------+| Database |+---------- ...
- ZROI-Day2比赛解题报告
ZROIDay2-比赛解题报告 版权原因不提供题面信息 序 这几天作息有点鬼畜,虽然昨晚很晚睡但是早上精神还不错,看到题发现T1很友好?T2woc这暴力都好难打?T3多项式?!这样下去比赛会不会出现更 ...