fzuoj 2186 小明的迷宫 bfs+bfs状压+剪枝
来源:互联网 发布:mac怎么压缩rar 编辑:程序博客网 时间:2024/05/21 17:21
Problem 2186 小明的迷宫
Accept: 137 Submit: 453
Time Limit: 1000 mSec Memory Limit : 32768 KB
Problem Description
小明误入迷宫,塞翁失马焉知非福,原来在迷宫中还藏着一些财宝,小明想获得所有的财宝并离开迷宫。因为小明还是学生,还有家庭作业要做,所以他想尽快获得所有财宝并离开迷宫。
Input
有多组测试数据。
每组数据第一行给出两个正整数n,m(0<n,m<=100)。代表迷宫的长和宽。
接着n行,每行m个整数。正数代表财宝(财宝的个数不超过10);负数代表墙,无法通过;0代表通道。
每次移动到相邻的格子,所花费的时间是1秒。小明只能按上、下、左、右四个方向移动。
小明的初始位置是(1,1)。迷宫的出口也在(1,1)。
Output
输出获得所有财宝并逃出迷宫所花费的最小时间,如果无法完成目标则输出-1。
Sample Input
3 30 0 00 100 00 0 02 21 11 1
Sample Output
44
思路:看了看网上写的都是用 bfs求最短路加dp的。我这里是用两个bfs做的。
两个bfs ,一个bfs 求(1,1)点到其他点的最短路径,还有一个 搜索。但是要注意一点的就是 这组数据
状压不懂得可以先看这里:
http://blog.csdn.net/lw277232240/article/details/75004165 有详细介绍状压
3 3
1 2 3
4 5 6
7 8 9
,这里搜到的最短路找完宝藏,有几处都是为8 所以要加上后面的dis【x】【y】,进行判断,要一个最短的。
还有一种数据就是起点是负数,这点也要考虑。
详细的见代码;
#include<stdio.h>#include<string.h>#include<stdlib.h>#include<queue>using namespace std;#define INF 999999999struct node{ int x,y;};struct node1{ int x,y; int step; int k;};int dis[101][101];bool vis[101][101][1025];int n,m;int dir[4][2]={1,0,-1,0,0,1,0,-1};int map[101][101];int count;int ans;int jude(int x,int y){ if(x<1||x>n||y<1||y>m) return 0; return 1;}void bfs(){ queue<node>q; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { dis[i][j]=INF; } } node a={1,1}; dis[1][1]=0; q.push(a); while(!q.empty()) { a=q.front(); q.pop(); for(int i=0;i<4;i++) { int xx=a.x+dir[i][0]; int yy=a.y+dir[i][1]; if(!jude(xx,yy)) continue; if(map[xx][yy]<0) continue; if(dis[xx][yy]>dis[a.x][a.y]+1) { dis[xx][yy]=dis[a.x][a.y]+1; node b={xx,yy}; q.push(b); } } }}void bfs2(){ memset(vis,0,sizeof(vis)); queue<node1>q; node1 a={1,1,0,0}; int end1=(1<<(count-1))-1; if(map[1][1]>0) { a.k=a.k|1<<(map[1][1]-1); } vis[a.x][a.y][a.k]=1; q.push(a); while(!q.empty()) { a=q.front(); q.pop(); if(a.k==end1)//全都找完了继续执行,怕有可能有比他小的dis【a.x】【a.y】; { if(ans>a.step+dis[a.x][a.y]) ans=a.step+dis[a.x][a.y]; continue ; } if(a.step+dis[a.x][a.y]>ans) continue;//当当前路径加上 跟 当前点到1,1点的最短路径大于ans 不进入循环。 for(int i=0;i<4;i++) { node1 b=a; b.x+=dir[i][0]; b.y+=dir[i][1]; b.step=a.step+1; if(!jude(b.x,b.y)) continue; if(map[b.x][b.y]<0) continue; if(map[b.x][b.y]>0) { int kk=b.k|(1<<(map[b.x][b.y]-1)); if(vis[b.x][b.y][kk]) continue; vis[b.x][b.y][kk]=1; b.k=kk; q.push(b); } else { if(vis[b.x][b.y][b.k]) continue; vis[b.x][b.y][b.k]=1; q.push(b); } } }}int main(){ while(scanf("%d%d",&n,&m)!=EOF) { count=1; memset(map,0,sizeof(map)); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { scanf("%d",&map[i][j]); if(map[i][j]>0) { map[i][j]=count++; } } } if(map[1][1]<0) { printf("-1\n"); continue; } bfs();//求1.1到其他点的最短路 int flag=0; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) if(map[i][j]>0&&dis[i][j]==INF)//当有宝藏的地方求不出最短路直接输出-1; { printf("-1\n"); flag=1; } } if(flag) continue; ans=INF; bfs2(); printf("%d\n",ans); }}
阅读全文
0 0
- fzuoj 2186 小明的迷宫 bfs+bfs状压+剪枝
- (BFS,状压DP)小明的迷宫
- FZU 2186 小明迷宫寻宝 (状压Dp+bfs)
- (福大2015年3月月赛)FZU 2186 小明的迷宫 (BFS+状压DP)
- Fzu 2186 小明的迷宫【Bfs预处理+TSP状压dp】好题~
- 挑战ACM迷宫 DFS+剪枝 BFS
- Fzu 2186 小明的迷宫(状态压缩dp + bfs)
- FZUoj 1408 位图【基础BFS】
- fzuoj 2150 Fire Game BFS
- BFS~~~迷宫
- BFS(迷宫)
- 迷宫-BFS
- BFS------迷宫
- 迷宫-BFS
- HDU 1728 逃离迷宫(dfs或bfs+剪枝)
- 搜索专题(DFS&&BFS&&剪枝)HDU 1728-逃离迷宫
- 迷宫问题的双向BFS
- BFS的应用-走迷宫
- C# 接收post到后台的json数据
- IDL之参数和关键字
- 十二天
- 多线程爬取糗事百事百科
- 可变字符串的基本操作
- fzuoj 2186 小明的迷宫 bfs+bfs状压+剪枝
- java从入门到入土(3)文件上传
- php中正则表达式详解
- 夜神,逍遥,天天连接AS
- Nginx配置文件详解
- ElasticSearch(map数据类型)Java api 增(批量)删改查(全字段、高亮)
- webpack构建工具安装
- 批量前移list中指定的元素
- 简述 synchronized 和 java.util.concurrent.locks.Lock 的异同 ?