我用的普通的宽搜去做的这道题,只不过在里面加了一个等待队列,确定一些@的点入队的时间,而且后进入队列的点一定比前面的步数要多,所以那也是一个非降序的队列
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<queue> 5 #define N 505 6 using namespace std; 7 int dir[4][2]={0,1,1,0,0,-1,-1,0}; 8 bool vis[N][N]; 9 struct node 10 { 11 int x,y; 12 int step; 13 }; 14 node wait[N*N]; 15 queue<node> q; 16 node sta; 17 node p1; 18 char map[N][N]; 19 int main() 20 { 21 int n,m,c; 22 int t,i,j; 23 scanf("%d",&t); 24 int xs,ys,xn,yn; 25 while(t--) 26 { 27 int ks,ke; 28 ks=ke=0; 29 scanf("%d%d%d",&n,&m,&c); 30 while(!q.empty()) 31 q.pop(); 32 for(i=0;i<n;i++) 33 scanf("%s",map[i]); 34 memset(vis,0,sizeof(vis)); 35 for(i=0;i<n;i++) 36 for(j=0;j<m;j++) 37 if(map[i][j]=='S') 38 { 39 xs=i; 40 ys=j; 41 } 42 else if(map[i][j]=='#') 43 vis[i][j]=true; 44 node pt; 45 sta.x=xs; 46 sta.y=ys; 47 sta.step=0; 48 q.push(sta); 49 vis[xs][ys]=true; 50 while(!q.empty()) 51 { 52 p1=q.front(); 53 q.pop(); 54 if(p1.x==0||p1.x==n-1||p1.y==0||p1.y==m-1) 55 { 56 printf("%d\n",p1.step+1); 57 break; 58 } 59 bool can=false; 60 for(i=0;i<4;i++) 61 { 62 xn=p1.x+dir[i][0]; 63 yn=p1.y+dir[i][1]; 64 if(xn>=0&&xn<n&&yn>=0&&yn<m&&!vis[xn][yn]) 65 { 66 vis[xn][yn]=true; 67 if(map[xn][yn]=='.') 68 { 69 pt.x=xn; 70 pt.y=yn; 71 pt.step=p1.step+1; 72 q.push(pt); 73 } 74 else 75 { 76 pt.x=xn; 77 pt.y=yn; 78 pt.step=p1.step+c+1; 79 wait[ke++]=pt;//把一些点暂时加入等待队列 80 } 81 } 82 } 83 while(ks<ke&&wait[ks].step==p1.step+1)//把等待队列里的能入队的入队 84 { 85 q.push(wait[ks]); 86 ks++; 87 } 88 //printf("%d %d %d %d %d\n",p1.x,p1.y,can,ks,ke); 89 if(q.empty())//当本层结束都没有可以接着入队的点时,将等待队列的第一层入队 90 { 91 q.push(wait[ks]); 92 ks++; 93 while(wait[ks].step==wait[ks-1].step&&ks<ke) 94 { 95 q.push(wait[ks]); 96 ks++; 97 } 98 } 99 } 100 } 101 return 0; 102 }