BFS对于最短路径问题的解决比DFS要快,一般DFS超时问题可以用BFS进行解决。
BFS要用到队列知识,笔者目前还没有深入学习数据结构知识,所以BFS用的不是特别熟练,以营救为例题进行BFS的练习与巩固。
【问题描述】
铁塔尼号遇险了!他发出了求救信号。距离最近的哥伦比亚号收到了讯息,时间就是生命,必须尽快赶到那里。
通过侦测,哥伦比亚号获取了一张海洋图。这张图将海洋部分分化成n*n个比较小的单位,其中用1标明的是陆地,用0标明是海洋。船只能从一个格子,移到相邻的四个格子。
为了尽快赶到出事地点,哥伦比亚号最少需要走多远的距离。
【输入格式】
第一行为n,下面是一个n*n的0、1矩阵,表示海洋地图
最后一行为四个小于n的整数,分别表示哥伦比亚号和铁塔尼号的位置。
【输出格式】
哥伦比亚号到铁塔尼号的最短距离,答案精确到整数。
【输入样例】save.in
3
001
101
100
1 1 3 3
【输出样例】save.out
4
【数据范围】
N<=1000
此题要注意的点:
1.搜索过的点不能重复搜索,搜索完成后将此点标记为“1”,即下次不能再次搜索次点
2.用path数组记录到达每一点的步数,此步数等于到达达到上一点的步数+1
#include<iostream>
#include<queue>
using namespace std;
struct pos {
int x, y;
};
int ocean[1005][1005], path[1005][1005], n, start_x, start_y, end_x, end_y, ans;//path记录到达各点的步数
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
int main(void)
{
char ch;
cin >> n;
for (int y = 1; y <= n; y++)
{
for (int x = 1; x <= n; x++)
{
cin >> ch;
if (ch == '1')
ocean[y][x] = 1;//0代表海洋,1代表陆地
}
}
cin >> start_x >> start_y >> end_x >> end_y;
ocean[start_y][start_x] = 1;//起点标记为已经遍历过了
pos p;
p.x = start_x; p.y = start_y;
queue<struct pos> qu;//用起点初始化队列
qu.push(p);
while (!qu.empty())//empty函数队列为空返回真
{
p = qu.front(); qu.pop();//队首元素出队并删除
if (p.x == end_x && p.y == end_y)//队首元素就是终点则对出循环
{
break;
}
for (int i = 0; i < 4; i++)//队首元素扩展出4个方向
{
int xx = p.x + dx[i];
int yy = p.y + dy[i];
if (!ocean[yy][xx] && xx >= 1 && xx <= n && yy >= 1 && yy <= n)
{
ocean[yy][xx] = 1;//走过的点标记后以后不能再走了
path[yy][xx] = path[p.y][p.x] + 1;
p.x = xx; p.y = yy;
qu.push(p);//满足条件的点入队
}
}
}
cout << path[end_y][end_x];
return 0;
}