Luogu 1979(BFS+SPFA)
来源:互联网 发布:ubuntu下载镜像方法 编辑:程序博客网 时间:2024/05/04 23:50
传送门
题解:先BFS预处理move[i][j][k][h]表示从(i,j),空格在k方向,走到h方向的最小步数。再对于考虑从S到T,每个状态dis[i][j][k]只能从它的相反状态dis[i][j][opp(k)]转移过来,所以可以视作有向图,进行SPFA。
注意的细节都在代码中。
小结:
1.将实格的移动考虑为空格的移动,很巧妙的转化!
2.初始化函数一定要放外面啊。。。不然叫什么预处理。。。疯狂TLE,100分强行变70分
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<queue>using namespace std;const int MAXN=32,INF=0x3f3f3f3f;int n,m,q,ex,ey,sx,sy,tx,ty;int move[MAXN][MAXN][5][5],dis[MAXN][MAXN][5],mp[MAXN][MAXN];bool inq[MAXN][MAXN][5];struct Node { int x,y,k;};inline bool in(Node a) { return a.x>0&&a.x<=n&&a.y>0&&a.y<=m;}inline int opp(int x) { switch (x) { case 1:return 2; case 2:return 1; case 3:return 4; case 4:return 3; }}Node step(Node a,int k) { Node t=a; if (k==1) t.x--; if (k==2) t.x++; if (k==3) t.y--; if (k==4) t.y++; return t;}inline int bfs(Node s,Node t) { if (!mp[s.x][s.y]||!mp[t.x][t.y]) return INF; queue<Node> q; int dep[MAXN][MAXN];bool vis[MAXN][MAXN]; memset(dep,INF,sizeof(dep)); memset(vis,false,sizeof(vis)); q.push(s),dep[s.x][s.y]=0,vis[s.x][s.y]=true; while (!q.empty()&&!vis[t.x][t.y]) { Node p=q.front();q.pop(); for (int i=1;i<=4;++i) { Node v=step(p,i); if (!in(v)) continue; if (mp[v.x][v.y]&&!vis[v.x][v.y]) { vis[v.x][v.y]=true; q.push(v); dep[v.x][v.y]=dep[p.x][p.y]+1; } } } return dep[t.x][t.y];}inline void init() { memset(move,INF,sizeof(move)); for (int i=1;i<=n;++i) for (int j=1;j<=m;++j) { if (!mp[i][j]) continue; mp[i][j]=0;//mark "vis" array for (int k=1;k<=4;++k) for (int h=1;h<=4;++h) { if (h<k) {move[i][j][k][h]=move[i][j][h][k];continue;} Node t1=step((Node){i,j},k),t2=step((Node){i,j},h); if (!in(t1)||!in(t2)) continue; if (!mp[t1.x][t1.y]||!mp[t2.x][t2.y]) continue; move[i][j][k][h]=bfs(t1,t2)+1; } mp[i][j]=1;//recover "vis" array }}inline int spfa(Node s,Node t) { if (s.x==t.x&&s.y==t.y) return 0; if (!mp[s.x][s.y]||!mp[t.x][t.y]) return INF; queue<Node> q; memset(dis,INF,sizeof(dis)); memset(inq,false,sizeof(inq)); mp[s.x][s.y]=0; for (int i=1;i<=4;++i) { Node tmp=step(s,i); if (!in(tmp)||!mp[tmp.x][tmp.y]) continue; q.push((Node){s.x,s.y,i}),inq[s.x][s.y][i]=true; dis[s.x][s.y][i]=bfs((Node){ex,ey},tmp); } mp[s.x][s.y]=1; while (!q.empty()) { Node p=q.front();q.pop(); inq[p.x][p.y][p.k]=false; for (int i=1;i<=4;++i) { Node v=step(p,i); v.k=opp(i); if (dis[v.x][v.y][v.k]>dis[p.x][p.y][p.k]+move[p.x][p.y][p.k][i]) {//i instead of v.k(关于p的位置) dis[v.x][v.y][v.k]=dis[p.x][p.y][p.k]+move[p.x][p.y][p.k][i]; if (!inq[v.x][v.y][v.k]) { inq[v.x][v.y][v.k]=true; q.push(v); } } } } int ans=INF; for (int i=1;i<=4;++i) ans=min(ans,dis[t.x][t.y][i]); return ans;}int main() {// freopen("codevs 3290.in","r",stdin); scanf("%d%d%d",&n,&m,&q); for (int i=1;i<=n;++i) for (int j=1;j<=m;++j) scanf("%d",&mp[i][j]); init(); while (q--) { scanf("%d%d%d%d%d%d",&ex,&ey,&sx,&sy,&tx,&ty);// init();//put outsiade!!! int ans=INF; ans=spfa((Node){sx,sy},(Node){tx,ty}); printf("%d\n",ans^INF?ans:-1); } return 0;}
阅读全文
0 0
- Luogu 1979(BFS+SPFA)
- Luogu 1186(SPFA)
- Luogu 1144(SPFA+dp)
- 华容道 洛谷1979 bfs+spfa
- noip2013 华容道 (bfs+spfa)
- [noip2013]华容道(bfs+spfa)
- Luogu 3387(tarjan+dp)(tarjan+SPFA)
- [BFS] [Luogu P1299] 切孔机
- 【NOIP2017】【Luogu P3956】【SPFA】棋盘
- SPFA判负环|BFS|DFS
- NOIP2013 华容道 [spfa+bfs]
- hdu3345[BFS和SPFA]
- Luogu 1514(BFS+贪心)(NOIP 2010)(引水入城)
- Luogu P1162填涂颜色 +BFS
- POJ 1860 Currency Exchange 最短路 BF & SPFA(bfs)
- HDU-1548 A strange lift(最短路[Spfa || BFS])
- NOIP2013 DAY2 T3 华容道(PUZZLE) BFS+SPFA
- [SCU 4498] RunningPhoton's Nightmare (BFS预处理+SPFA)
- java学习笔记1
- NOI-OJ逆波兰表达式
- mybatis加jdbctype,jdbctype和javatype区别mybatis插入insert空指针无效字符
- HDU 3466|Proud Merchants|01背包|贪心
- shell学习十三--分支与循环
- Luogu 1979(BFS+SPFA)
- 详解比较好的音视频通话SDK开发包的技术要点
- 欢迎使用CSDN-markdown编辑器
- java发送邮件封装类
- 架构师四十八个阶段高端课
- Java PIO读取Excel文件
- java中函数是值传递还是引用传递?
- Apache的DBUtils框架学习
- mac 上mysql 安装