第七章 图(POJ3984图的DFS、BFS+记录路径问题)

来源:互联网 发布:惊艳句子知乎 编辑:程序博客网 时间:2024/06/11 11:05

迷宫问题 POJ - 3984

定义一个二维数组:

int maze[5][5] = {

0, 1, 0, 0, 0,0, 1, 0, 1, 0,0, 0, 0, 0, 0,0, 1, 1, 1, 0,0, 0, 0, 1, 0,

};

它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。
Input
一个5 × 5的二维数组,表示一个迷宫。数据保证有唯一解。
Output
左上角到右下角的最短路径,格式如样例所示。
Sample Input
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
Sample Output
(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)

【bfs被坑的错误代码】

/*    这个代码坑了我的点:    1.print_path函数坑我的点已经注释    2.最坑的地方是我记录路径的方法,我用next数组来记录路径,    仔细想想,用脑走一下bfs就知道next是不对的,比如下面这个:    0 1 1 1 1    0 1 1 1 1    0 0 1 1 1    0 1 1 1 1    0 0 0 0 0    如果进队顺序是(0,0),(1,0),(2,0),(3,0),(2,1)这样的话,由    原来的next[2][0].x=3,next[2][0].y=0变成了next[2][0].x=2,    next[2][0].y=1,接着继续进队的是(3,0),但是(2,0)和(3,0)    已经失去了联系。所以还是用pre数组来记录路径是没问题的,    这里就是一对多改成了多对一,多对一是完全正确的,好似函数    的概念乎!    上面的第2个坑点导致了死循环的出现。(next数组是全局的,    其所有值默认为0)*/#include<iostream>#include<queue>#include<cstring>using namespace std;int a[10][10];bool vis[10][10];int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};typedef struct{    int x,y;}point;point next[10][10];void input();void bfs();void print_path();int main(){    input();    bfs();    print_path();    return 0;}void input(){    for(int i=0;i<5;i++)        for(int j=0;j<5;j++)            cin>>a[i][j];}void bfs(){    memset(vis,0,sizeof(vis));    point p,q;    p.x=p.y=0;    queue<point>que;    que.push(p);    vis[p.x][p.y]=1;    while(!que.empty()){        if(p.x==4 && p.y==4) break;        p=que.front();        que.pop();        int xx,yy;        for(int i=0;i<4;i++){            xx=p.x+dir[i][0];            yy=p.y+dir[i][1];            if(xx>=0 && xx<=4 && yy>=0 && yy<=4 && !a[xx][yy] && !vis[xx][yy]){                q.x=xx;                q.y=yy;                que.push(q);                vis[xx][yy]=1;                next[p.x][p.y].x=xx;                next[p.x][p.y].y=yy;            }        }    }}void print_path(){    int x=0,y=0;    while(!(x==4 && y==4)){        cout<<"("<<x<<", "<<y<<")"<<endl;        /*            坑我的点:            下面这么写的话,上一个x改变后,影响了下一个式子中的x,导致错误            x=next[x][y].x;            y=next[x][y].y;        */        int xx=next[x][y].x;        int yy=next[x][y].y;        x=xx;        y=yy;    }}

【BFS,ac代码】

#include<iostream>#include<queue>#include<cstring>using namespace std;int a[10][10];bool vis[10][10];int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};typedef struct{    int x,y;}point;point pre[10][10];void input();void bfs();void print_path();int main(){    input();    bfs();    print_path();    return 0;}void input(){    for(int i=0;i<5;i++)        for(int j=0;j<5;j++)            cin>>a[i][j];}void bfs(){    memset(vis,0,sizeof(vis));    point p,q;    p.x=p.y=4;    queue<point>que;    que.push(p);    vis[p.x][p.y]=1;    while(!que.empty()){        if(p.x==0 && p.y==0) break;        p=que.front();        que.pop();        int xx,yy;        for(int i=0;i<4;i++){            xx=p.x+dir[i][0];            yy=p.y+dir[i][1];            if(xx>=0 && xx<=4 && yy>=0 && yy<=4 && !a[xx][yy] && !vis[xx][yy]){                q.x=xx;                q.y=yy;                que.push(q);                vis[xx][yy]=1;                pre[xx][yy].x=p.x;                pre[xx][yy].y=p.y;            }        }    }}void print_path(){    int x=0,y=0;    while(!(x==4 && y==4)){        cout<<"("<<x<<", "<<y<<")"<<endl;        int xx=pre[x][y].x;        int yy=pre[x][y].y;        x=xx;        y=yy;    }    cout<<"("<<x<<", "<<y<<")"<<endl;}

【DFS,ac代码】

#include<iostream>#include<stack>#include<cstring>using namespace std;int mp[10][10];bool vis[10][10];int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};typedef struct{    int x,y;}point;stack<point>sta;int mmin=1000;point path[100];void input();void dfs(int x,int y,int step);void update_path(stack<point>sta);void print_path();int main(){    input();    memset(vis,0,sizeof(vis));    dfs(0,0,1);    print_path();    return 0;}void input(){    for(int i=0;i<5;i++)        for(int j=0;j<5;j++)            cin>>mp[i][j];}void dfs(int x,int y,int step){    point p;p.x=x;p.y=y;    sta.push(p);    vis[x][y]=1;    if(x==4 && y==4){        if(step<mmin){            mmin=step;            update_path(sta);        }    }    //下面循环控制深搜结束(四个方向深搜如下)    for(int i=0;i<4;i++){        int xx=x+dir[i][0];        int yy=y+dir[i][1];        if(xx>=0 && xx<=4 && yy>=0 && yy<=4 && !mp[xx][yy] && !vis[xx][yy]){            vis[xx][yy]=1;            dfs(xx,yy,step+1);            vis[xx][yy]=0;//走过的路重新标记为0,可以再次走该点        }    }    sta.pop();//对于某点,四个方向都不能走,就退回上一个点,相应路径点出栈}//下面函数中注意要带参数,如果没有参数,直接对全局变量sta操作,是明显错误的void update_path(stack<point>sta){    for(int i=(int)sta.size();i>=1;i--){        path[i]=sta.top();        sta.pop();    }}void print_path(){    for(int i=1;i<=mmin;i++){        cout<<"("<<path[i].x<<", "<<path[i].y<<")"<<endl;    }}
原创粉丝点击