传说中的经典好题(BFS+记录路径)
学下记录路径
http://acm.hdu.edu.cn/showproblem.php?pid=1026
题解:超级普通的BFS板子+加上平淡无奇的回溯;
BFS好说,但记录回溯时因为有一个记录打怪兽的的标记,所以以前用的前驱数组记录用不出来,这时看见某位大佬的博客尽然还有这种操作二维数组的结构体(第一次见),这就好办啦,记录路径,最后用栈输出就可以了。
重要的是不能用普通队列,得用优先队列,因为为了加快速度,因为要打怪,会有好几个选择,当然要时间最少的第一时间弹出来
优先队列默认弹最大值,所以得重载<号
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<stdlib.h>
#include<queue>
#include<stack>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1000000;
char a[500][500];
int vis[500][500];
int n,m;
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
struct node {
int x;
int y;
int t;
bool operator<(const node &a) const//优先队列 重载 < 号
{
return t>a.t;// t小的优先级高
}
};
struct node2{
int x;
int y;
int flag=0;
}pre[500][500];
bool judge(int x,int y){
if(x>=0&&y>=0&&x<m&&y<n&&a[x][y]!='X'){
return true;
}
return false;
}
void inp(int k){栈特性实现 记录路劲
printf("It takes %d seconds to reach the target position, let me show you the way.\n",k);
stack<node2>s;
struct node2 tmpe;
tmpe.x=m-1;
tmpe.y=n-1;
tmpe.flag=0;
s.push(tmpe);
int x,y;
x=m-1;
y=n-1;
while(1){
int nx,ny;
nx=x;
ny=y;
s.push(pre[nx][ny]);
x=pre[nx][ny].x;
y=pre[nx][ny].y;
if(x==0&&y==0) break;
// tmpe.x=pre[tmpe.x][tmpe.y].x; // 错了 原因
// tmpe.y=pre[tmpe.x][tmpe.y].y; //这里的tmpe.x已不是原来的tmpe.x
// tmpe.flag=pre[tmpe.x][tmpe.y].flag;
// if(tmpe.x==0&&tmpe.y==0)
// break;
// s.push(tmpe);
}
struct node2 na;
struct node2 nb;
int p=0;
while(!s.empty()){
p++;
na=s.top();
s.pop();
nb=s.top();
printf("%ds:(%d,%d)->(%d,%d)\n",p, na.x ,na.y ,nb.x ,nb.y);
if(na.flag!=0){
while(na.flag--){
p++;
printf("%ds:FIGHT AT (%d,%d)\n",p, nb.x ,nb.y);
}
}
if(nb.x==m-1&&nb.y==n-1) break;
}
printf("FINISH\n");
}
void bfs(int x,int y){
priority_queue<node> q;
struct node tmp;
tmp.x=x;
tmp.y=y;
tmp.t=0;
q.push(tmp);
vis[x][y]=1;
while(!q.empty()){
struct node now;
now=q.top();
q.pop();
if(now.x==m-1&&now.y==n-1){
//cout<<now.t<<endl;
inp(now.t);
return;
}
for(int i=0;i<4;i++){
int nx=now.x+dx[i];
int ny=now.y+dy[i];
if(!vis[nx][ny]&&judge(nx,ny)){
if(a[nx][ny]!='.'){
tmp.t=now.t+a[nx][ny]-'0' + 1;// 不光打怪兽还要走到这格
pre[nx][ny].x=now.x;
pre[nx][ny].y=now.y;
pre[nx][ny].flag=a[nx][ny]-'0';
}else{
tmp.t=now.t+1;
pre[nx][ny].x=now.x;
pre[nx][ny].y=now.y;
pre[nx][ny].flag=0;
}
tmp.x=nx;
tmp.y=ny;
q.push(tmp);
vis[nx][ny]=1;
}
}
}
cout<<"God please help our poor hero."<<endl;
cout<<"FINISH"<<endl;
return ;
}
int main(){
while(~scanf("%d%d",&m,&n)){
memset(vis,0,sizeof(vis));
for(int i=0;i<m;i++){
scanf("%s",a[i]);
}
bfs(0,0);
}
return 0;
}