我们先从一个简单的例题开始。

搜索+保存路径_数组

这道题可以用广搜也可以用深搜,先说深搜吧

无非就是保存路径麻烦一点。我们可以这样,在函数体参数中加入一个数组,保存当前走过的路径。走到终点时,如果比原来路径短,就赋值给记录最终结果的全局变量数组里。当然要注意的一点是,函数体里无法直接改变形参,所以我另外用了pos数组中转,具体请看代码。

#include <bits/stdc++.h>
using namespace std;
int a[10][10];
int ans,b[5]={0,0,1,-1},c[5]={1,-1,0,0},vis[10][10];
int temp[50][10];
void dfs(int x,int y,int sumn,int lu[][10])
{
if(x==4&&y==4)
{
if(sumn<ans)
{
for(int i=0;i<sumn;i++)
{
temp[i][0]=lu[i][0];
temp[i][1]=lu[i][1];
}
ans=sumn;
}
return;
}
int pos[50][10];//中转数组
for(int j=0;j<=sumn;j++)
{
pos[j][0]=lu[j][0];
pos[j][1]=lu[j][1];
}
for(int i=0;i<4;i++)
{
int xx=x+b[i],yy=y+c[i];
if(xx>=0&&yy>=0&&xx<5&&yy<5&&vis[xx][yy]==0&&a[xx][yy]==0)
{
vis[xx][yy]=1;
pos[sumn+1][0]=xx;pos[sumn+1][1]=yy;
dfs(xx,yy,sumn+1,pos);
// vis[xx][yy]=0;//确实是可以不回溯的
}
}
}
int main()
{
for(int i=0;i<5;i++)
{
for(int j=0;j<5;j++)
{
cin>>a[i][j];
}
}
ans=999;
int z[50][10];
memset(z,0,sizeof(z));
dfs(0,0,0,z);
for(int i=0;i<ans;i++)
{
cout<<"("<<temp[i][0]<<", "<<temp[i][1]<<")"<<endl;
}
cout<<"("<<4<<", "<<4<<")"<<endl;
}

然后是广搜。

广搜的话就比较巧妙了,它另外开了一个数组记录路径,核心就是这条语句。

搜索+保存路径_广搜_02

这条语句是在新节点temp入队列后紧接着执行的语句。

有了这条语句,因为我们已知终点位置,所以终点的上一个位置就是cnt[终点.x] [终点.y]。由于每次我们都是这么记录的,所以以上一个位置作为索引,可以得到上上个位置的值,这个仔细想想就好理解了。

#include <bits/stdc++.h>
using namespace std;
struct p
{
int x,y;
}cnt[100][100];
queue<p> a;
int b[10][10],vis[10][10];
int c[5]={0,0,1,-1},d[5]={1,-1,0,0};
void bfs()
{
p init;
init.x=0;init.y=0;
a.push(init);
vis[0][0]=1;
while(!a.empty())
{
p ans;
ans=a.front();
if(ans.x==4&&ans.y==4)
return;
a.pop();
for(int i=0;i<4;i++)
{
p temp;
temp.x=ans.x+c[i];temp.y=ans.y+d[i];
if(temp.x>=0&&temp.y>=0&&temp.x<5&&temp.y<5&&b[temp.x][temp.y]==0&&vis[temp.x][temp.y]==0)
{
vis[temp.x][temp.y]=1;
a.push(temp);
// cnt[ans.x][ans.y]=temp;//这里不要搞混了!
cnt[temp.x][temp.y]=ans;
}
}
}
}
int main()
{
for(int i=0;i<5;i++)
{
for(int j=0;j<5;j++)
cin>>b[i][j];
}
bfs();
p lll[50];//数组储存路径
p ff=cnt[4][4];
int k=0;
while(!(ff.x==0&&ff.y==0))
{
lll[k]=ff;
ff=cnt[ff.x][ff.y];
k++;
}
cout<<"(0, 0)"<<endl;
for(int i=k-1;i>=0;i--)//倒序输出
cout<<"("<<lll[i].x<<", "<<lll[i].y<<")"<<endl;
/* stack<p>v;//注释部分是用栈实现的
p ff = cnt[4][4];
while(!(ff.x==0&&ff.y==0)){
v.push(ff);
ff = cnt[ff.x][ff.y];
}
printf("(0, 0)\n");
while(!v.empty()){
printf("(%d, %d)\n",v.top().x,v.top().y);
v.pop();
}*/
printf("(4, 4)\n");
return 0;
}