BFS
此题与普通的BFS不同的是它的路径可以重复走,虽然空间代价不大(8*8),但
是如果你不能很好的判断没有出路的情况,那么就会陷入死循环。我是这么想的:我
先定义一个标记数组mark[][],出发点赋值为6。当你走到4时,那点的mark[][]值赋
为6。每次进队列时判断,如果当前点的mark值大于新生成点的mark时,才能进队列,
否则不能,这样就防止了进入死循环的情况。使用mark数组就省略了标记数组vis
不过,有一点,我始终不解,一到达终点就退出,这样保证了时间最短吗?可还是过了,困惑……
当然,也有遍历完所有点的
#include<iostream> #include<queue> using namespace std; int map[9][9],mark[9][9],n,m,mins,si,sj; int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; //mark[][]保存到达该点时所剩的时间 struct node { int x,y,time,cnt;//time 剩余时间;cnt 已花时间 }; node f; void bfs() { f.x=si;f.y=sj; f.cnt=0;f.time=6; queue<node> q; q.push(f); mark[si][sj]=6; while(!q.empty()) { node t=q.front(); q.pop(); if(map[t.x][t.y]==3) { if(t.time>0) { mins=t.cnt; return; } else continue; } if(map[t.x][t.y]==4)//重置时间 { t.time=6; mark[t.x][t.y]=6; } for(int k=0;k<4;k++) { node b; b.x=t.x+dir[k][0]; b.y=t.y+dir[k][1]; b.cnt=t.cnt+1; b.time=t.time-1; if(b.x<=n&&b.x>0&&b.y<=m&&b.y>0&&map[b.x][b.y]!=0&&t.time>0&&mark[b.x][b.y]<b.time)//只有mark[b.x][b.y]<b.time时,才有必要入队 { mark[b.x][b.y]=b.time; q.push(b); } } } } int main() { int t; cin>>t; while(t--) { cin>>n>>m; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { cin>>map[i][j]; if(map[i][j]==2) si=i,sj=j; mark[i][j]=0; } } mins=1000; bfs(); if(mins!=1000) cout<<mins<<endl; else cout<<"-1"<<endl; } }