https://vjudge.net/contest/230934#problem/K
思路:
在广搜时每一步都记入队列,通过每一个点向外发射,把每种可能都一次加进队列里,每一次扩展完一个地点就让它出队,继续下一个点的扩展,在结构体中声明多一个数组变量edge[].pre来记录每一个点的来源,即某一步是从哪一步扩展来的,方便输出结果时的追踪。
利用函数的调用,对每一点都倒向追踪回去,确定是前一步是哪个点,然后返回输出追溯的每一步。
代码:
#include<iostream>
#include<string.h>
using namespace std;
int map[5][5];
int vis[5][5];
struct node {
int x;
int y;
int pre;
}edge[100];
int front = 0, rear = 1;//队头,队尾
int dir[4][2] = { { 0,-1 },{ 1,0 },{ 0,1 },{ -1,0 } };//向外搜索的方向
void f(int i)
{
//倒向追踪法
if (edge[i].pre != -1)
{
f(edge[i].pre);// 找出每一步是从哪上一步进行扩展的。
cout << "(" << edge[i].x << ", " << edge[i].y << ")" << endl;
}
}
void BFS(int x, int y)
{
edge[front].x = x;
edge[front].y = y;
edge[front].pre = -1;
while (front<rear)//队列为空时终止
{
int u;
for (u = 0; u<4; u++)
{
int x = edge[front].x + dir[u][0];
int y = edge[front].y + dir[u][1];
if (x<0 || x >= 5 || y<0 || y >= 5 || vis[x][y] == 1 || map[x][y] == 1)
continue;
else
{
vis[x][y] = 1;
map[x][y] = 1;
edge[rear].x = x;//入队
edge[rear].y = y;
edge[rear].pre = front; //记录每一步的来源
rear++;
}
if (x == 4 && y == 4)//最先达到说明是最短路径
f(front);
}
front++;//指针头指向下一个,让队列中的第一个出队,因为它已经扩展过了;
}
}
int main()
{
int i, j;
for (i = 0; i<5; i++)
{
for (j = 0; j<5; j++)
{
cin >> map[i][j];
}
}
memset(vis, 0, sizeof(vis));
cout << "(" << "0, 0)" << endl;
BFS(0, 0);
cout << "(4, 4)" << endl;
return 0;
}