UVA 1600 Patrol Robert 巡逻机器人 (启发搜索BFS)

非常适合A*的一道题。

比普通的迷宫问题加一个信息k表示当前穿过的障碍物的数量。

#include<cstdio>

#include<cstring>

#include<queue>

using namespace std;

const int MAX = 21;



int m,n,k;



int C[MAX][MAX][MAX];

int G[MAX][MAX];



int tarx,tary;

struct node

{

   int g,h;

   int x,y;//对于本题 x+y 越大距离终点越近

   int k;

   bool operator < (const node& rhs) const{

      if(g + h > rhs.g + rhs.h) return true;

      if(g + h < rhs.h + rhs.g ) return false;

      if(g > rhs.g) return true;

      if(g < rhs.g) return false;

      return k > rhs.k;

   }

   void H(){

      h = tarx - x+ tary - y;

   }

};







node start;



#define C(n) C[n.x][n.y][n.k]

#define add(n) C(n) = true

int dx[] = { 0, 1, 0,-1};

int dy[] = { 1, 0,-1, 0};



int bfs()

{

   priority_queue<node> q;

   memset(C,false,sizeof(C));

   q.push(start); add(start);

   node cur,nxt;

   int i,nx,ny,nk;

   while(q.size()){

      cur = q.top();q.pop();

      if(cur.x == tarx && cur.y == tary) return cur.g;

      for(i = 0; i < 4; i++){

         nx = cur.x + dx[i];

         ny = cur.y + dy[i];

         if(nx >= m || nx < 0 || ny >= n || ny < 0 )continue;

         nk = G[nx][ny] ? cur.k+1 : 0;

         if(C[nx][ny][nk] || nk > k) continue;

         nxt.x = nx ; nxt.y = ny; nxt.g = cur.g+1 ; nxt.k = nk ; nxt.H();

         q.push(nxt); add(nxt);

      }

   }

   return -1;

}



int main()

{

  // freopen("in.txt","r",stdin);

   int T;

   int i,j;

   scanf("%d",&T);

   while(T--){

      scanf("%d%d%d",&m,&n,&k);

      for(i = 0;i < m; i++)

         for(j = 0;j < n; j++)

           scanf("%d",G[i]+j);

      tarx = m-1;tary = n-1;

      start.x = start.y = start.g = start.k = 0;

      //start.H();

      printf("%d\n",bfs());

   }

   return 0;

}

 

你可能感兴趣的:(bfs)