杭电 1072题

//迷宫求解的变形:广度优先搜索
//关键解决重复回路问题
#include <iostream>
using namespace std;
int n,m;
int map[10][10];
int mark[10][10]; //该地的剩余时间
int sj,sk,ej,ek;
int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}}; //遍历的四个方向
int mintime =0;
typedef struct node
{
 int x;
 int y;
 int step;
 int time;
}node;
node myqueue[100]; //维持广度优先搜索中的队列
void BFS()
{
 int i,j;
 memset(mark,0,sizeof(mark));
 int start = 0;
 int end =1;
 myqueue[0].x = sj;
 myqueue[0].y = sk;
 myqueue[0].step = 0;
 myqueue[0].time = 6;
 node frontnode,nextnode;
 while(end!=start)
 {
  frontnode = myqueue[start];
  start++;
  //在进行四个方向遍历时考虑(1)是否值得加入到队列中(判断当前剩余时间与该点剩余时间)(2)是否是出口(3)是否是炸弹重置器
  for(i=0;i<4;++i)
  {
   nextnode.x = frontnode.x + dir[i][0];
   nextnode.y = frontnode.y + dir[i][1];
   nextnode.step = frontnode.step+1;
   nextnode.time = frontnode.time-1;
   if(nextnode.time <= mark[nextnode.x][nextnode.y]) //本题的关键:是否值得加入到队列中(判断当前剩余时间与该点剩余时间),从而解决重复回路问题 
    continue;
   if(nextnode.time>0 && nextnode.x>=0 && nextnode.x < n && nextnode.y >=0 && nextnode.y<m && map[nextnode.x][nextnode.y]!=0)
   {
    if(map[nextnode.x][nextnode.y] == 3)
    {
     mintime = nextnode.step;
     return;
    }
    else if(map[nextnode.x][nextnode.y]==4)
     nextnode.time = 6;
    mark[nextnode.x][nextnode.y] = nextnode.time;
    myqueue[end] = nextnode;
    end++;
   }
  }
 }
}
int main()
{
 //freopen("1.txt","r",stdin);
 int t;
 int i,j,k;
 cin>>t;
 for(i=0;i<t;++i)
 {
  cin>>n>>m;
  for(j=0;j<n;++j)
  {
   for(k=0;k<m;++k)
   {
    cin>>map[j][k];
    if(map[j][k]==2)
    {
     sj = j;
     sk = k;
    }     
   }
  }
  mintime = 0;  //记录所用的最小时间
  BFS();
  if(mintime>0)
   cout<<mintime<<endl;
  else
   cout<<-1<<endl;
 }
 return 0;
}

你可能感兴趣的:(杭电)