bfs 管窥 poj3984

来源:互联网 发布:简单图表制作软件 编辑:程序博客网 时间:2024/06/05 03:06

第一次接触bfs,刚开始感觉比较难,看很多文章都看不懂,做题还是先看别人的代码,然后自己写注释,这次居然连代码都看不懂。。。

第一次看的代码,中间有些不知道是什么意思:

#include<iostream>#include<queue>using namespace std;//广搜,并输出路径;struct point{int x,y;};//定义点;struct node{int x,y,i;point r[25];};//定义迷宫;int map[5][5];//存储迷宫;int dx[4]={0,1,0,-1};int dy[4]={1,0,-1,0};//点移动的变量;int ok(int x,int y){if(x>=0&&x<5&&y>=0&&y<5)return 1;return 0;}//确定迷宫内的点:范围是5X5;void bfs(){int i,j,x,y,flag=0;queue<node> q;//定义队列 q,表示迷宫内的点;node n1;//迷宫对象;n1.x=0;//初始化迷宫第一格为0.0;n1.y=0;n1.i=1;n1.r[0].x=0;//第一个的元素是(0.0)n1.r[0].y=0;map[0][0]=1;//标记第一格为1;q.push(n1);//把第一迷宫加入队列,队尾入队;while(!q.empty())//判定迷宫非空{   if(flag)break;//如果是1,则循环结束;   node tmp;//定义节点 tmp   tmp=q.front();//指向队首的指针   q.pop();//队头出队   for(i=0;i<4;i++)//四周延伸;   {    if(flag)break;//判定是否为1;    x=tmp.x+dx[i];    y=tmp.y+dy[i];//移动后的坐标;    if(ok(x,y)&&!map[x][y])//判定坐标在迷宫中;    {     node n2;     n2.x=x;     n2.y=y;//对象N2 并初始化;     for(j=0;j<tmp.i;j++)     {      n2.r[j].x=tmp.r[j].x;      n2.r[j].y=tmp.r[j].y;     }//把路径的点的坐标赋给n2     n2.i=tmp.i+1;//步数加1?     n2.r[n2.i-1].x=x;     n2.r[n2.i-1].y=y;     q.push(n2);//n2加入队列     map[x][y]=1;//加入后迷宫元素变为1,     if(x==4&&y==4)     {      for(j=0;j<n2.i;j++)printf("(%d, %d)\n",n2.r[j].x,n2.r[j].y);      flag=1; //输出路径并使循环停止        }    }   }}}int main()//主函数;{int i,j;for(i=0;i<5;i++)for(j=0;j<5;j++)scanf("%d",&map[i][j]);bfs();return 0;}

注释完之后还是有很多不明白的地方。。但是还是有很多值得学习的地方比如点的移动算法,还有其他语言方面的知识;

来,我有无意之间找到一个代码,我感觉这是我见到的最简单的bfs代码了:

#include <iostream>  #include <cstdio>  #include <cstring>  #include <cmath>  #include <ctime>  #include <queue>  #include <stack>  #include <vector>  #include <algorithm>  #include <string> #include <stdlib.h> using namespace std;  #define forl(i,a,b)  for(int i=(a);i<(b);++i)  #define forle(i,a,b) for(int i=(a);i<=(b);++i)  #define forg(i,a,b)  for(int i=(a);i>(b);--i)  #define forge(i,a,b) for(int i=(a);i>=(b);--i)  #define mes(a,v)  memset(a, v, sizeof (a) );  #define cpy(a,b)  memcpy(a, b, sizeof (a) );  #define mesn(a, v, n) memset(a, v, (n)*sizeof((a)[0]))  #define cpyn(a, b, n) memcpy(a, v, (n)*sizeof((a)[0]))  const int dx[]={1,0,0,-1};  const int dy[]={0,1,-1,0};  int visit[200],pre[200],maze[10][10];  void print_ans(int st)  //输出路径的方式  {                       //用pre[next]=now表示,子节点next的父亲为now      if(pre[st]!=-1)          print_ans(pre[st]);      printf("(%d, %d)\n",st/5,st%5);  }  void Bfs()      //标准的BFS模板  {      queue<int>q;      q.push(0);      visit[0]=1;      pre[0]=-1;      while(!q.empty())      {          int now=q.front();          q.pop();          int x=now/5;          int y=now%5;          for(int i=0;i<4;i++)          {              int nex=x+dx[i];              int ney=y+dy[i];              int next=nex*5+ney;              if(!visit[next]&&!maze[nex][ney]&&nex>=0&&nex<5&&ney>=0&&ney<5)              {                  pre[next]=now;                  if(next==24)    return;                  q.push(next);                  visit[next]=1;              }          }      }  }  int main()  {      //freopen("in.txt","r",stdin);      int i,j;      for(i=0;i<5;i++)          for(j=0;j<5;j++)              scanf("%d",&maze[i][j]);      Bfs();      print_ans(24);      //for(int i=0;i<=24;i++)        //  cout<<pre[i]<<' ';        system("PAUSE");    return 0;  }  

ps:大神们原来是把自己知道的所有的头文件和定义全部写出来,下面不用考虑直接就用了,真是比较方便。。。


看了几个小时终于弄懂bfs的基本过程和含义了,自己写出代码:

poj3984:AC

#include<iostream>#include<queue>using namespace std;int now,next;int map[5][5];int lujing[26],visit[26];int dx[4]={1,0,0,-1};int dy[4]={0,1,-1,0};void shuchu(int p){if (lujing[p]!=-1)     shuchu(lujing[p]);     cout<<"("<<p/5<<", "<<p%5<<")"<<endl;     }void bfs(){     queue<int>q;     q.push(0);     lujing[0]=-1;     visit[0]=1;     while(!q.empty()){     now=q.front();     q.pop();     int x=now/5;     int y=now%5;     for(int k=0;k<4;k++){            int nex=x+dx[k];            int ney=y+dy[k];            int next=nex*5+ney;             if(!visit[next]&&!map[nex][ney]&&nex>=0&&nex<5&&ney>=0&&ney<5){             lujing[next]=now;             if(next==24)return;             q.push(next);             visit[next]=1;             }          }    }}int main(){    for(int m=0;m<5;m++)    for(int n=0;n<5;n++)    cin>>map[m][n];    bfs();    shuchu(24);    return 0;}         

ps当时第一次交的时候显示显示PE,仔细一看居然是输出少个空格,以后做题要注意不能在这种细节上出问题~~




总体来说还是可以的,和二叉树一样耗时两天,看4篇以上代码才知道是什么意思,然后半默出自己的代码~~

    

原创粉丝点击