关于广搜的学习

来源:互联网 发布:知堂回想录下载 编辑:程序博客网 时间:2024/06/11 17:46
/**在学习图论的过程中感觉求最短路算是比较简单的题了,直接广搜就可以了但是很多时候不会这么简单,BFS算法求出来的最优解一般是步数最少的解,但是步数最少有时并不是最优解,比如图具有权值的时候,要求权值最小,或要求权值最大,亦或者下面这个有路障的题,简单的求出步数最小并不是最优解。**************************************************************************以下题做个分析:这个题是有路障的情况下求最少时间到达目标节点的问题,可以用BFS解决,但是要对该算法做一下改动,首先定义一个结构体用来存放当前位置的状态记录当前位置的坐标,走过的步数,用掉的时间,需要注意的是,在搜索的过程中,不能一判断到达目标节点就退出搜索,因为此时求得的仅仅是起点到目标节点最小步数的几个方案中的最小时间,不一定是最优解;因此需要等到队列为空,此时方可得出最少时间,或者无法到达目标节点的结论。*/#include<stdio.h>#include<string.h>#include<queue>#define INF 1234567using namespace std;int n,m;///n*m的图char a[1000][1000];///图int dir[4][2]= {{-1,0},{0,1},{1,0},{0,-1}};///对应的四个方向int mintime[1000][1000];///用于标记到达每一个点最小时间状态/**用一个结构体表示到达每个点的状态*/typedef struct{    int x, y;///点的位置    int step;///走到当前位置所走的步数    int time;///走到当前位置所花的时间} Step;Step start , End;///用于表示起点,和终点int BFS(){    ///搜索前的准备工作    queue<Step>q;    start.step = 0;    start.time = 0;    mintime[start.x][start.y] = 0;    Step node, new_node;    q.push(start);    while(!q.empty())    {        node = q.front();        q.pop();        for(int i = 0; i < 4; i++)///从当前层,一层一层的向外扩充节点,        {                         ///若无特殊情况,到达每一层的步数和时间都是相等的            int x = node.x + dir[i][0];            int y = node.y + dir[i][1];            if(x>=0 && x<n && y>=0 && y<m && a[x][y] != '#')            {                new_node.x = x;                new_node.y = y;                new_node.step = node.step + 1;                new_node.time = node.time + 1;                if(a[x][y] == 'x')///遇到路障时时间增加                    new_node.time++;                ///如果以当前节点到达目标节点所花的时间比之前走到(x,y)所用的时间更少                ///new_node 进队,否则无需进队                if(new_node.time < mintime[new_node.x][new_node.y])///判断当前时间是否做过记录,若没有记录下当前时间                {                    mintime[new_node.x][new_node.y] = new_node.time;                    q.push(new_node);                }            }        }    }    return mintime[End.x][End.y];}int main(){    while(~scanf("%d%d%d",&n,&m)&&(n+m))    {        memset(a,0,sizeof(a));        for(int i = 0; i < n; i++)        {            scanf("%s",a[i]);            for(int j = 0; j < m; j++)            {                if(a[i][j] == 'r')                {                    start.x = i;                    start.y = j;                }                else if(a[i][j] == 'a')                {                    End.x = i;                    End.y = j;                }            }        }        for(int i = 0; i <= n; i++)            for(int j = 0; j <=m; j++)                mintime[i][j] = INF;        int mint = BFS();        if(mint < INF)            printf("%d\n",mint);        else            printf("no come");    }    return 0;}

0 0
原创粉丝点击