POJ_4115,有穿墙次数(能量)的BFS题目,代码有所参考
#include
#include
using namespace std;
struct point{
//该点的行列,到达用时,剩余能量,能否不消耗能量通过
int r,c,alltime,chance;
bool cango;
}points[200][200];
queue <point> q;
int row,col,endr,endc;
int bfs(){
while(!q.empty()){
point curr=q.front();
q.pop();
if(curr.r==endr && curr.c==endc) return curr.alltime;
int choose[4][2]={{curr.r-1,curr.c},{curr.r+1,curr.c},{curr.r,curr.c-1},{curr.r,curr.c+1}};
for(int i=0;i<4;i++){
int nextr=choose[i][0],nextc=choose[i][1];
//不同于普通BFS,除了边界这里检查的不是该点是否访问过,而是要到达该点的能量是否大于之前的
//原因是若之前该点的能量小于这次的,说明上次路径未能到达终点,不然到达该点的能量只会相等或更小(又消耗了能量)
//而如果上次就能到达终点的话,把这个点处理后不会对结果有影响(因为该点只走一次就到达终点,不会再返回来走)
if(nextr>=0 && nextc>=0 && nextr<row && nextc<col && curr.chance>points[nextr][nextc].chance){
points[nextr][nextc].alltime=curr.alltime+1;
points[nextr][nextc].chance=curr.chance;
if(points[nextr][nextc].cango) q.push(points[nextr][nextc]);
else if(curr.chance>0){
points[nextr][nextc].chance--;
q.push(points[nextr][nextc]);
}
}
}
}
return -1;
}
int main(){
int chance; cin>>row>>col>>chance;
for(int i=0;i<row;i++)
for(int j=0;j<col;j++){
points[i][j].r=i;
points[i][j].c=j;
points[i][j].alltime=0;
//初始能量是-1(与上方BFS对应)
points[i][j].chance=-1;
char c; cin>>c;
if(c=='#') points[i][j].cango=0;
else{
points[i][j].cango=1;
if(c=='@'){
points[i][j].chance=chance;
q.push(points[i][j]);
}
else if(c=='+'){
endr=i;
endc=j;
}
}
}
cout<<bfs();
}