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 ...
随机推荐
- ######<待随时补充>我的学习规划######
一.关于Python 1.demo 一些基础实验,包含Python基础知识等,约300-500个 2.Python常见模块的了解学习,如 time datetime random 随机数 os 与 ...
- Web循环监控Java调用 / Java调用.net wcf接口
背景介紹 (Background Introduction) 目前有一些报表客户抱怨打不开 报表执行过程过长,5.8.10秒甚至更多 不能及时发现和掌握服务器web站点情况 用戶需求(User Req ...
- Tensorflow安装错误Cannot uninstall wrapt
解决办法:安装之前先执行:pip install wrapt --ignore-installed
- Scala学习六——对象
一.本章要点 用对象作为但例或存放工具的方法 类可以拥有一个同名的伴生对象 对象可以扩展类或特质 对象的apply方法通常用来构造伴生类的新实例 如果不想显示定义main方法,可以扩展App特质的对象 ...
- Python(八) —— 异常(概念、捕获、传递、抛出)
异常的概念 捕获异常 异常的传递 抛出异常 异常的概念 程序在运行时,如果 Python 解释器 遇到 到一个错误,会停止程序的执行,并且提示一些错误信息,这就是 异常 程序停止执行并且提示错误信息 ...
- Linux Permission denied 问题
Linux Permission denied 问题 来源 https://www.cnblogs.com/sparkdev/p/10287164.html 如果当前用户没有某个文件的写权限,又要通 ...
- JS基础_while的练习1
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- webpack中使用html-webpack-plugin生成HTML文件并主动插入css和js引入标签
html-webpack-plugin clean-webpack-plugin 一.html-webpack-plugin 由于打包时生成的css样式文件和js脚本文件会采用hash值作为文件命名的 ...
- mysql 批量 insert 数据丢失问题
这两天发现mysql 批量insert 比如600条数据后,页面马上select就查询到580条,但是等几秒钟再查询就有600条(也有部分情况是永久只能查到580条了) 查看mybatis的日志发现循 ...
- vue中使用proxy配置不同端口和ip接口
问题描述: 使用vue-cli创建的项目,开发地址是localhost:8080,由于后台开发不同的模块,导致每个模块请求的ip和端口号不一致 例如:http://192.168.10.22:8081 ...