题目链接:http://poj.org/problem?id=3984
题目分析:
本题是要在图中找一条从0,0到4,4的路,如果用dfs做的话,找到的可能不是最短路,所以用bfs。从一点出发,将与他相连的所有没有搜过的点加入队列,并将这些点的父节点设成这个点,当搜到4,4这个点时,最短路就形成了。用bfs找到最短路后,再往回找,输出整条路径,为每个结点都设置一个父节点,用于回溯。设置一个结构体来保存点的坐标和父节点。详见代码注释:
c++代码:
#include<iostream>
using namespace std;
int edge[5][5];
//设置点的四个搜索方向
int dict[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
int front=0,rear=1;
struct Node
{
int x,y,pre;
}node[100];
//用来输出结点
void print(int i)
{
//如果还没递归到起点
if(node[i].pre!=-1)
{
//因为要从起点输出到终点,所以先递归,再输出
print(node[i].pre);
cout<<"("<<node[i].x<<", "<<node[i].y<<")"<<endl;
}
}
void bfs(int x1,int y1)
{
//给起点的父节点设为-1
node[front].x=x1;
node[front].y=y1;
node[front].pre=-1;
//当队列不为空
while(front<rear)
{
//遍历这个点四个方向上的点
for(int i=0;i<4;i++)
{
//先判断点的合法性
int a=node[front].x+dict[i][0];
int b=node[front].y+dict[i][1];
if(a<0 || a>4 || b<0 || b>4 || edge[a][b])
continue;
//将这个点设为1表示搜索过了,然后入队
edge[a][b]=1;
node[rear].x=a;
node[rear].y=b;
node[rear].pre=front;
rear++;
//如果搜到了就输出结果
if(a==4 && b==4)
{
print(front);
break;
}
}
front++;
}
}
int main()
{
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)
cin>>edge[i][j];
//起点和终点单独输出
cout<<"(0, 0)"<<endl;
bfs(0,0);
cout<<"(4, 4)"<<endl;
return 0;
}