​点击打开链接​

还是bfs+优先队列 难点就是保存节点

此题用STL的优先队列 但麻烦就是弹出的节点无法保存 求路径比较麻烦

不用STL的话模拟这个过程又太麻烦..

最后想出再开个专门存 路径中某节点的父节点位置  的二维结构体数组

虽然由起点至终点每个点最多可向三个方向各自扩展出一个子节点 哪个方向的子节点才是最短路径中的节点无法确定

但是从终点回溯 其父节点是唯一的 因此最终递归输出就可

 

 

#include <stdio.h>
#include <queue>
using namespace std;

struct node
{
friend bool operator< (node n1,node n2)
{
return n1.s>n2.s;
}
int x;
int y;
int s;
};

struct spot
{
int fx;
int fy;
};

struct spot last[100][100];
int book[100][100];
int n,m,time,px,py,flag,num;
char map[100][101];

void bfs();
void output(int x,int y);

int main()
{
int i,j;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i=0;i<n;i++)
{
scanf("%s",map[i]);
}
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
book[i][j]=0;
}
}
flag=0;
bfs();
if(flag==1)
{
printf("It takes %d seconds to reach the target position, let me show you the way.\n",time);
num=1;
output(px,py);
}
else
{
printf("God please help our poor hero.\n");
}
printf("FINISH\n");
}
return 0;
}

void bfs()
{
priority_queue <struct node> que;
struct node cur,t;
int next[4][2]={0,-1,-1,0,0,1,1,0};
int i,tx,ty;
t.x=0;
t.y=0;
t.s=0;
que.push(t);
book[0][0]=1;
last[0][0].fx=-1;
last[0][0].fy=-1;
while(!que.empty())
{
cur=que.top();
que.pop();
for(i=0;i<4;i++)
{
tx=cur.x+next[i][0];
ty=cur.y+next[i][1];
if(tx<0||tx>n-1||ty<0||ty>m-1||map[tx][ty]=='X'||book[tx][ty]==1)
{
continue;
}
t.x=tx;
t.y=ty;
t.s=cur.s+1;
if(map[tx][ty]>='1'&&map[tx][ty]<='9')
{
t.s+=(map[tx][ty]-'0');
}
que.push(t);
book[tx][ty]=1;
last[tx][ty].fx=cur.x;
last[tx][ty].fy=cur.y;
if(tx==n-1&&ty==m-1)
{
flag=1;
px=tx,py=ty,time=t.s;
return;
}
}
}
return;
}

void output(int x,int y)
{
int i;
if(last[x][y].fx==-1&&last[x][y].fy==-1)
{
return;
}
output(last[x][y].fx,last[x][y].fy);
printf("%ds:(%d,%d)->(%d,%d)\n",num++,last[x][y].fx,last[x][y].fy,x,y);
if(map[x][y]>='1'&&map[x][y]<='9')
{
for(i=0;i<map[x][y]-'0';i++)
{
printf("%ds:FIGHT AT (%d,%d)\n",num++,x,y);
}
}
return;
}