关于 BFS 中 打印路径的问题
2016-04-17 21:41
357 查看
打印路径可以用栈的方式, 也可以用递归。下面看看用递归做的吧还是NYOJ 最少步数那道题
#include <iostream> #include<queue> #include<cstring> #include<cstdio> const int dx[4] = {0, 0,-1, 1}; const int dy[4] = {-1,1, 0, 0}; struct node { int x, y; int step; }; int x1, y1, x2, y2; node now, next; node S,E; using namespace std; bool vis[10][10]; node qq[10][10]; int map[9][9] = {1,1,1,1,1,1,1,1,1 , 1,0,0,1,0,0,1,0,1 ,1,0,0,1,1,0,0,0,1 ,1,0,1,0,1,1,0,1,1 ,1,0,0,0,0,1,0,0,1 ,1,1,0,1,0,1,0,0,1 ,1,1,0,1,0,1,0,0,1 ,1,1,0,1,0,0,0,0,1 ,1,1,1,1,1,1,1,1,1}; int bfs() { if(S.x == E.x && S.y == E.y) return 0; memset(vis, false,sizeof(vis)); queue<node>q; q.push(S); vis[S.x][S.y] = true; while(!q.empty()) { now = q.front(); q.pop(); for(int i=0; i<4; i++) { next.x = now.x + dx[i]; next.y = now.y + dy[i]; next.step = now.step + 1; if(map[next.x][next.y] == 1||next.x > 9 || next.x<0 || next.y>9 || next.y<0 || vis[next.x][next.y]) continue; vis[next.x][next.y] = true; qq[next.x][next.y].x = now.x; qq[next.x][next.y].y = now.y; q.push(next); if(next.x == E.x && next.y == E.y) return next.step; } } return -1; } void pri(int sx, int sy) { if( sx==x1 && sy==y1 ) { printf("(%d, %d)\n", sx, sy); return ; } pri(qq[sx][sy].x, qq[sx][sy].y); printf("(%d, %d)\n", sx, sy); } int main() { int T; cin >> T; while(T--) { cin >> x1 >> y1; cin >> x2 >> y2; S.x = x1; S.y = y1; S.step = 0; E.x = x2; E.y = y2; int ans = bfs(); if(ans >= 0) { cout << ans << endl; pri(x2, y2); } } return 0; }下面是用栈实现的:
#include <iostream>#include<queue>#include<cstring>#include<stack>const int dx[4] = {0, 0,-1, 1};const int dy[4] = {-1,1, 0, 0};struct node{int x, y;int step;};int x1, y1, x2, y2;node now, next;node S,E;node Pre[10][10];using namespace std;bool vis[10][10];int map[9][9] = {1,1,1,1,1,1,1,1,1, 1,0,0,1,0,0,1,0,1,1,0,0,1,1,0,0,0,1,1,0,1,0,1,1,0,1,1,1,0,0,0,0,1,0,0,1,1,1,0,1,0,1,0,0,1,1,1,0,1,0,1,0,0,1,1,1,0,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1};int bfs(){if(S.x == E.x && S.y == E.y)return 0;memset(vis, false,sizeof(vis));queue<node>q;q.push(S);vis[S.x][S.y] = true;while(!q.empty()){now = q.front();q.pop();for(int i=0; i<4; i++){next.x = now.x + dx[i];next.y = now.y + dy[i];next.step = now.step + 1;if(map[next.x][next.y] == 1||next.x > 9 || next.x<0 || next.y>9 || next.y<0 || vis[next.x][next.y])continue;vis[next.x][next.y] = true;Pre[next.x][next.y] = now;q.push(next);if(next.x == E.x && next.y == E.y)return next.step;}}return -1;}void PrintPath(int row,int column){//输出最短路径node temp; //保存位置stack<node> s; //保存路径序列temp.x = row;temp.y = column;while(temp.x != x1 || temp.y != y1){s.push(temp);temp = Pre[temp.x][temp.y];}cout<<"(" << x1 << "," << y1 << ")" << endl;while(!s.empty()){temp = s.top();cout<<"("<<temp.x<<","<<temp.y<<")" << endl;s.pop();}cout<<endl;}int main(){int T;cin >> T;while(T--){cin >> x1 >> y1;cin >> x2 >> y2;S.x = x1;S.y = y1;S.step = 0;E.x = x2;E.y = y2;int ans = bfs();if(ans >= 0){cout << ans << endl;PrintPath(x2, y2);}}return 0;}/*23 1 5 712(3,1)(4,1)(4,2)(4,3)(4,4)(5,4)(6,4)(7,4)(7,5)(7,6)(7,7)(6,7)(5,7)3 1 6 711(3,1)(4,1)(4,2)(4,3)(4,4)(5,4)(6,4)(7,4)(7,5)(7,6)(7,7)(6,7)Process returned 0 (0x0) execution time : 24.583 sPress any key to continue.*/再做做下面这道题, 越来越发现应该学会融会贯通啊!题目描述:一个网格迷宫由n行m列的单元格组成,每个单元格要么是空地(用1表示),要么是障碍物(用0来表示)。你的任务是找一条从起点到终点的最短步数和移动序列,其中UDLR表示上下左右操作。任何时候都不能在障碍物格子中,也不能走到迷宫之外。起点和终点保证都是空地。n,m<100。样例输入:6 5110111011110100101111110111111样例输出:9DDDDDRRRR解题思路:较上一个文章来说,只是多了输出路径,这里既然题目没规定入口出口,为了方便起见,我人为的把入口和出口规定为左上角和右下角。记录路径即需要知道终点是由那个点走到的,而这个点的上一个点也需要知道……所以就记录下每个点的父节点和相应的操作,然而准备输出路径的时候又遇到了一个问题:从出口一步步向上寻找,是一个倒着的,怎么才能正着输出呢?先进后出这个特点是栈对应的特点,而递归类似栈,所以利用递归的方式,达到按顺序输出的目的。代码:[cpp] viewplain copy#include<cstdio>#include<queue>#include<iostream>using namespace std;char mmap[10][10]={};int vis[10][10]={};int n,m;int xx[4]={1,0,0,-1};int yy[4]={0,1,-1,0};struct node{int x,y;int t;};struct father{int x,y;//当前格子的父节点坐标char cz;//由什么操作到达的这个格子};queue<node> q;node s,f;father lj[10][10];//记录路径int bfs(){int i,j;s.x=0;s.y=0;s.t=0;f.x=n-1;f.y=m-1;q.push(s);lj[s.x][s.y].x=1000;//因为m,n<=100lj[s.x][s.y].y=1000;lj[s.x][s.y].cz=0;vis[s.x][s.y]=1;//标为已经访问过while(!q.empty()){node now=q.front();q.pop();for(i=0;i<4;++i){node New;New.x=now.x+xx[i];New.y=now.y+yy[i];New.t=now.t+1;if(New.x<0||New.y<0||New.x>=n||New.y>=m||vis[New.x][New.y]||mmap[New.x][New.y]=='0')//下标越界或者访问过或者是障碍物continue;q.push(New);lj[New.x][New.y].x=now.x;lj[New.x][New.y].y=now.y;if(i==0) lj[New.x][New.y].cz='D';else if(i==1) lj[New.x][New.y].cz='R';else if(i==2) lj[New.x][New.y].cz='L';else if(i==3) lj[New.x][New.y].cz='U';vis[New.x][New.y]=1;if(New.x==f.x&&New.y==f.y) return New.t;//到达终点}}return -1;}void dfs(int x, int y){if(x==0&&y==0) return;//找到父节点是起点的格子了elsedfs(lj[x][y].x,lj[x][y].y);printf("%c",lj[x][y].cz);}int main(){int i,j,ans;scanf("%d%d",&n,&m);for(i=0;i<n;++i){scanf("%s",mmap[i]);}ans=bfs();if(ans<0) printf("error");else{printf("%d\n",ans);dfs(n-1,m-1);//从终点开始找他的父节点}return 0;}
相关文章推荐
- 高精度加法
- html网页设计
- 网络图 可视化
- nginx+tomcat+memcached实现session共享
- Boosting与Bagging
- 【UNET自学日志】Part5 解决延迟产生的画面不流畅问题
- 学习 Spark Streaming 的重要性
- Android学习(26) -- 数据存储之SQLite数据库的创建
- uva 10154 - Weights and Measures【dp】qi
- 静态代理
- Java数据结构与排序算法——堆和堆排序
- 业务中是否有必要让所有的ViewController统一继承抽象类
- jsp 自定义标签
- 1004 Toxophily
- 周易六十四卦——噬嗑卦
- RecyclerView
- 这恼人的一星期
- 开源后5个月,Google的深度学习都有哪些改变?
- RelativeLayout.addRule()方法
- LeetCode|Two Sum