思路:广度优先遍历矩阵。代价相同的图中,广度优先遍历可以保证遍历到的目标点就是经过最短路径到达的点。为此,我们可以创建一个Point类,属性为横纵坐标和父节点。从(0,0)出发,将经过的坐标点都设为1,避免重复经过而进入死循环。把当前点的上下左右值为0的点都加入队列中,直到遇见出口为止。遇到出口时,pos的father路径就是最短路径的逆路径。此时只需要把逆路径反转一下即可。当然我们可以利用递归可以后序输出链表的特性,省去反转路径的操作。
Java版本:
class Point{
int px;
int py;
Point father;
Point(int px,int py,Point father){
this.px=px;
this.py=py;
this.father = father;
}
Point(){}
}
public class Main{
public static void print(Point p){
if(p != null){
print(p.father);
System.out.println("("+p.px+","+p.py+")");
}
}
public static void main(String args[]){
Scanner sc = new Scanner(System.in);
while(sc.hasNextInt()){
int row = sc.nextInt();
int col = sc.nextInt();
int [][] grid = new int[row][col];
for(int i=0;i<row;++i){
for(int j=0;j<col;++j){
grid[i][j]=sc.nextInt();
}
}
Queue<Point> que = new LinkedList<Point>();
que.offer(new Point(0,0,null));
grid[0][0]=1;
Point pos = null;
while(true){
pos = que.poll();
int px = pos.px;
int py = pos.py;
if(px==row-1&&py==col-1)break;
else {
if(px+1<row&&grid[px+1][py]==0){
grid[px+1][py]=1;
que.offer(new Point(px+1,py,pos));
}
if(py-1>=0&&grid[px][py-1]==0){
grid[px][py-1]=1;
que.offer(new Point(px,py-1,pos));
}
if(px-1>=0&&grid[px-1][py]==0){
grid[px-1][py]=1;
que.offer(new Point(px-1,py,pos));
}
if(py+1<col&&grid[px][py+1]==0){
grid[px][py+1]=1;
que.offer(new Point(px,py+1,pos));
}
}
}
print(pos);
}
}
}
CPP版本
#include <bits/stdc++.h>
#include <cstddef>
using namespace std;
class Pos {
public:
int px;
int py;
Pos *father;
Pos(int px, int py, Pos *father): px(px), py(py), father(father){
}
};
void print_road(Pos *p, Pos *q)
{
if(q != NULL) {
print_road(p, q -> father);
cout << "(" + to_string(q -> px) + "," + to_string(q -> py) + ")" << endl;
}
}
int main()
{
int x, y;
cin >> x;
cin >> y;
vector<vector<int>> mat;
for(int i = 0; i < x; ++i) {
vector<int> vec;
for(int j = 0; j < y; ++j) {
int temp;
cin >> temp;
vec.push_back(temp);
}
mat.push_back(vec);
}
queue<Pos *> que;
Pos *p = new Pos(0, 0, NULL);
Pos *q;
Pos *temp;
que.push(p);
mat[0][0] = 1;
while(true) {
q = que.front();
que.pop();
if(q -> px == x - 1 && q ->py == y - 1) {
print_road(p, q);
return 0;
} else {
int pxa1 = q -> px + 1;
int pxm1 = q -> px - 1;
int pya1 = q -> py + 1;
int pym1 = q -> py - 1;
if(pxa1 < x && mat[pxa1][q -> py] == 0) {
mat[pxa1][q ->py] = 1;
temp = new Pos(pxa1, q ->py, NULL);
temp -> father = q;
que.push(temp);
}
if(pxm1 >= 0 && mat[pxm1][q ->py] == 0) {
mat[pxm1][q ->py] = 1;
temp = new Pos(pxm1, q ->py, NULL);
temp ->father = q;
que.push(temp);
}
if(pya1 < y && mat[q ->px][pya1] == 0) {
mat[q ->px][pya1] = 1;
temp = new Pos(q ->px, pya1, NULL);
temp ->father = q;
que.push(temp);
}
if(pym1 >= 0 && mat[q ->px][pym1] == 0) {
mat[q ->px][pym1] = 1;
temp = new Pos(q ->px, pym1, NULL);
temp ->father = q;
que.push(temp);
}
}
}
return 0;
}