bfs对路径有条件(必须拿到某个东西)
2016-08-22 18:25
134 查看
一个bfs,但标记的数组变化一下,变成三维数组;其中一维变成标记状态(已经拿过或者暂时没有拿过)用的;其余的都不变;
详情看例子;;;
hdu2612;
题目链接;http://acm.split.hdu.edu.cn/showproblem.php?pid=2612;
题目大意;地图里面有YM两个人,@kfc,#墙,.路,他们两个人要在地图里面找到一个@kfc,使得两者到它的距离之和最短;
思路;因为bfs就是最优的,就是最短的距离;因此直接使用bfs从Y到M;但是中间要保证经过@ok;否则不能;
关键在于怎么实现bfs从Y到M并且经过@呢????
还是使用标记方法;把普通bfs的是否走过的标记变化一下;
判断是否走过;该题因变化成分状态的是否走过;相同状态的不能再入队列了;
两种状态;
1;已经经过过@的;
2;暂时还没有经过@的;
还要注意一下;这个状态是伴随每个格子的;因此也要是结构体元素;然而要进行初始化;最开始状态应该都是没有经过过@的;;;怎么在结构体里面对元素进行初始化;
看bfs的代码;
完整代码;
详情看例子;;;
hdu2612;
题目链接;http://acm.split.hdu.edu.cn/showproblem.php?pid=2612;
题目大意;地图里面有YM两个人,@kfc,#墙,.路,他们两个人要在地图里面找到一个@kfc,使得两者到它的距离之和最短;
思路;因为bfs就是最优的,就是最短的距离;因此直接使用bfs从Y到M;但是中间要保证经过@ok;否则不能;
关键在于怎么实现bfs从Y到M并且经过@呢????
还是使用标记方法;把普通bfs的是否走过的标记变化一下;
判断是否走过;该题因变化成分状态的是否走过;相同状态的不能再入队列了;
两种状态;
1;已经经过过@的;
2;暂时还没有经过@的;
还要注意一下;这个状态是伴随每个格子的;因此也要是结构体元素;然而要进行初始化;最开始状态应该都是没有经过过@的;;;怎么在结构体里面对元素进行初始化;
struct node { int x, y,step,flag; node() { this->flag = 0;//对每个flag进行初始化;为0; } };
看bfs的代码;
bool mark[210][210][2];//又是三维数组;另外一维是标记状态用的 void bfs() { queue<node>q; memset(mark,0,sizeof(mark)); node now, next; now.x=si;now.y=sj;now.step=0; q.push(now); mark[si][sj][0]=1;//表示si,sj这个点在没有拿到@的经过过了;; while(!q.empty()) { now = q.front(); q.pop(); //printf("%d %d %d\n",now.x,now.y,flag); for(int i = 0; i < 4; i++) { int a = now.x+dir[i][0]; int b = now.y+dir[i][1]; next.flag = now.flag;//赋值状态 if(now.x==ei && now.y==ej && now.flag == 1)//成功达到目的地; { printf("%d\n",now.step*11); return ; } if(a >= 0 && a < n && b >= 0 && b < m && mp[a][b] != '#') { if(mp[a][b]=='@') { next.flag = 1; } if(mark[a][b][next.flag]==1)//与普通的bfs一样;标记作用。但这里表示每个格子在不同状态是否走过;一个位置有俩个状态 continue; next.x=a;next.y=b;next.step=now.step+1; q.push(next); } } } }
完整代码;
#include<stdio.h> #include<stdlib.h> #include<math.h> #include<iostream> #include<queue> #include<algorithm> #include<stack> #include<set> #include<string.h> using namespace std; struct node { int x, y,step,flag; node() { this->flag = 0; } }; char mp[210][210]; bool mark[210][210][2]; int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; int n, m,si,sj,ei,ej; void bfs() { queue<node>q; memset(mark,0,sizeof(mark)); node now, next; now.x=si;now.y=sj;now.step=0; q.push(now); mark[si][sj][0]=1; while(!q.empty()) { now = q.front(); q.pop(); //printf("%d %d %d\n",now.x,now.y,flag); for(int i = 0; i < 4; i++) { int a = now.x+dir[i][0]; int b = now.y+dir[i][1]; next.flag = now.flag; if(now.x==ei && now.y==ej && now.flag == 1) { printf("%d\n",now.step*11); return ; } if(a >= 0 && a < n && b >= 0 && b < m && mp[a][b] != '#') { if(mp[a][b]=='@') { next.flag = 1; } if(mark[a][b][next.flag]==1)//与普通的bfs一样;标记作用。但这里表示每个格子在不同状态是否走过;一个位置有俩个状态 continue; next.x=a;next.y=b;next.step=now.step+1; q.push(next); } } } } int main() { int i,j; while(~scanf("%d %d",&n,&m)) { for(i = 0; i < n; i++) { scanf("%s",mp[i]); for(j = 0; j < m; j++) { if(mp[i][j]=='Y'){si=i;sj=j;} if(mp[i][j]=='M'){ei=i;ej=j;} } } bfs(); } return 0; }
相关文章推荐
- Oracle db规范之 database所在路径和归档目录所在路径必须分开
- hdu 1254 推箱子(bfs判断路径可达+bfs搜索最小)
- 看完越狱20件必须懂的东西(转)
- 一些面试的时候必须要背出来的东西(2)
- SDUTOJ 3058 路线冲突问题 ——bfs记录路径
- bfs应用最短路径查找--三道基础题
- 【DFS/BFS】NYOJ-58-最少步数(迷宫最短路径问题)
- remainder(bfs路径打印)
- POJ 3414 Pots ( BFS , 打印路径 )
- poj 3984 (bfs+输出路径)
- 学mysql必须了解的东西
- 你必须找到你所钟爱的东西
- 各种关联关系对象间 添加依赖。代码实现注意:###### 必须先拿到持久态的对象。再对其添加依赖
- poj 3414 Pots(bfs+string(储存路径))
- 如果你想拥有从未有过的东西,那么你必须去做你从未做过的事
- POJ 1606 Jugs(BFS:找最短路径并输出)
- BFS和DFS的差别,BFS实现迷宫最短路径
- dfs+bfs(三种路径问题)
- 07-图5 Saving James Bond - Hard Version(30 分)BFS记录路径
- c++ exception必须知道的东西(1)