BFS优点:求最短距离问题
题目:
移动距离:
根据代码,q数组依次存入
0:(0,0)
1:(1,0)
2:(2,0)
3:(2,1),(3,0)
4:(2,2),(4,0)
5:(1,2),(2,3),(4,1)
6:(0,2),(2,4),(4,2)
7:(0,3),(1,4),(3,4)
8:(0,4),(4,4)
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef pair<int, int> PII;
const int N = 110;
int n, m;
int g[N][N], d[N][N]; //g[][]存输入的数组,d[][]存每个点到起点的距离
PII q[N*N];
int bfs()
{
int hh=0,tt=0; //队头,队尾
q[0]={0,0};
memset(d, -1, sizeof d); //距离初始化为-1,表示这个点没有走过
d[0][0] = 0; //表示已经走过
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; //四个方向用向量表示:左(-1,0)右(0,1)上(1,0)下(0,-1);所以横坐标(-1,0,1,0),纵坐标(0,1,0,-1)
while (hh<=tt) //队列不空
{
auto t = q[hh++]; //取出队头
cout<<"hh="<<hh<<' '<<"t="<<t.first<<' '<<t.second<<endl;
for (int i = 0; i < 4; i ++ ) //枚举四个方向
{
int x = t.first + dx[i], y = t.second + dy[i]; //表示沿这个方向能走到哪个点
cout<<"x="<<x<<' '<<"y="<<y<<endl;
if (x >= 0 && x < n && y >= 0 && y < m && g[x][y] == 0 && d[x][y] == -1) //方向在边界内并且该点没有走过并且能走
{
d[x][y] = d[t.first][t.second] + 1; //把该点扩展出来
cout<<"d[x][y]="<<d[x][y]<<endl;
q[++tt]={x, y};
}
}
}
cout<<"d[n-1][m-1]="<<d[n-1][m-1]<<endl;
return d[n - 1][m - 1]; //把右下角点的距离输出来
}
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i ++ )
for (int j = 0; j < m; j ++ )
cin >> g[i][j];
cout << bfs() << endl;
return 0;
}
代码1:手打队列
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef pair<int, int> PII;
const int N = 110;
int n, m;
int g[N][N], d[N][N]; //g[][]存输入的数组,d[][]存每个点到起点的距离
PII q[N*N];
int bfs()
{
int hh=0,tt=0; //队头,队尾
q[0]={0,0};
memset(d, -1, sizeof d); //距离初始化为-1,表示这个点没有走过
d[0][0] = 0; //表示已经走过
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; //四个方向用向量表示:左(-1,0)右(0,1)上(1,0)下(0,-1);所以横坐标(-1,0,1,0),纵坐标(0,1,0,-1)
while (hh<=tt) //队列不空
{
auto t = q[hh++]; //取出队头
for (int i = 0; i < 4; i ++ ) //枚举四个方向
{
int x = t.first + dx[i], y = t.second + dy[i]; //表示沿这个方向能走到哪个点
if (x >= 0 && x < n && y >= 0 && y < m && g[x][y] == 0 && d[x][y] == -1) //方向在边界内并且该点没有走过并且能走
{
d[x][y] = d[t.first][t.second] + 1; //把该点扩展出来
q[++tt]={x, y};
}
}
}
return d[n - 1][m - 1]; //把右下角点的距离输出来
}
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i ++ )
for (int j = 0; j < m; j ++ )
cin >> g[i][j];
cout << bfs() << endl;
return 0;
}
代码2:STL队列
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 110;
int n, m;
int g[N][N], d[N][N]; //g[][]存输入的数组,d[][]存每个点到起点的距离
struct node
{
int x,y;
};
int bfs()
{
queue<node>q;
node tmp;
tmp.x=0;
tmp.y=0;
q.push(tmp);
memset(d, -1, sizeof d); //距离初始化为-1,表示这个点没有走过
d[0][0] = 0; //表示已经走过
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; //四个方向用向量表示:左(-1,0)右(0,1)上(1,0)下(0,-1);所以横坐标(-1,0,1,0),纵坐标(0,1,0,-1)
while (!q.empty()) //队列不空
{
node x=q.front(); //取出队头
q.pop();
for (int i = 0; i < 4; i ++ ) //枚举四个方向
{
int u = x.x + dx[i], v = x.y + dy[i]; //表示沿这个方向能走到哪个点
tmp.x=u;tmp.y=v;
if (u >= 0 && u < n && v >= 0 && v < m && g[u][v] == 0 && d[u][v] == -1) //方向在边界内并且该点没有走过并且能走
{
d[u][v] = d[x.x][x.y] + 1; //把该点扩展出来
q.push(tmp);
}
}
}
return d[n - 1][m - 1]; //把右下角点的距离输出来
}
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i ++ )
for (int j = 0; j < m; j ++ )
cin >> g[i][j];
cout << bfs() << endl;
return 0;
}