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; }