最短路一般使用广度优先的方法最好。
一道可以改变搜索深度的题目,一开始想用深搜+广搜每次扩展可行路径的方式加大搜索有效性,但是写不出来,也不知道可不可行,可能复杂化了
1.每次去搜索节点时,。除了可设置点‘4’外,其它不记录已经搜索过,搜索过的节点每次判断当前可以继续使用的时间是否更优。如果更优则加入队列。
否则:
2.如果原队列里的节点已经可以达到要求,那么新添加的节点一定不是最优,而且不会首先出队,故不会影响最优结果
3.如果队列的节点不满足那么新更新的节点可能可以达到最优值。
4.规模小,可以重复搜索是关键,否则算法要求更高。

#include <stdio.h> #include <queue> using namespace std; int t ,n , m ,sx,sy; int maz[11][11],stp[11][11] , tim[11][11]; const int dx[] = {1,0,-1,0}; const int dy[] = {0,1,0,-1}; int bfs(){ queue<int> q; memset(tim , 0 , sizeof(tim)); memset(stp , 0 , sizeof(stp)); q.push(sx*m+sy); stp[sx][sy] = 0; tim[sx][sy] = 6; while(!q.empty()){ int tn = q.front(); q.pop(); int x = tn / m , y = tn % m; if(maz[x][y]==3) return stp[x][y]; for(int i=0;i<4;i++){ int nx = x + dx[i],ny=y+dy[i]; if(nx >=0 && nx < n && ny >= 0 && ny < m && tim[x][y] > 0 && maz[nx][ny]!=0){ int _t; if(maz[nx][ny] == 4 && tim[x][y]-1 > 0) _t=6; else _t = tim[x][y]-1; if(_t <= 0) continue; if(stp[nx][ny]>0){ if(tim[nx][ny] >= _t) continue; } tim[nx][ny]=_t; stp[nx][ny] = stp[x][y] + 1; q.push(nx * m + ny); } } } return -1; } int main() { int T; scanf("%d",&T); while(T--){ scanf("%d %d",&n,&m); for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ scanf("%d",&maz[i][j]); if(maz[i][j]==2) sx=i,sy=j; } } printf("%d " , (t = bfs()) > 0 ? t : -1); } return 0; }