POJ 2312Battle City(BFS-priority_queue 或者是建图spfa)

简介:
/*
    bfs搜索!要注意的是点与点的权值是不一样的哦!
   空地到空地的步数是1, 空地到墙的步数是2(轰一炮+移过去)
   所以用到优先队列进行对当前节点步数的更新!
*/
#include<iostream>
#include<queue>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;

int n, m;
char map[305][305];

struct node{
    int x, y;
    int step;
    node(){}
    node(int x, int y, int step){
       this->x=x;
       this->y=y;
       this->step=step;
    }
};
int dir[4][2]={0, 1, 1, 0, -1, 0, 0, -1};

bool operator >(node a, node b){
   return a.step > b.step;
}

priority_queue<node, vector<node>, greater<node> >q;

bool bfs(){
   while(!q.empty()){
       node cur=q.top();
       q.pop();
       if(map[cur.x][cur.y]=='T'){
           cout<<cur.step<<endl;
           return true;
       }
       int xx, yy;
       for(int i=0; i<4; ++i){
           xx=cur.x+dir[i][0];
           yy=cur.y+dir[i][1];
           if(map[xx][yy]=='R' || map[xx][yy]=='S') continue;
           else if(map[xx][yy]=='T'){
              cout<<cur.step+1<<endl;
              return true;
           }
           else if(map[xx][yy]=='B')
              q.push(node(xx, yy, cur.step+2)); 
           else
              q.push(node(xx, yy, cur.step+1)); 
           
           map[xx][yy]='R';
       } 
   }
   return false;
}

int main(){
    while(cin>>n>>m && (n || m)){
        for(int i=1; i<=n; ++i){
            cin>>(map[i]+1);
            map[i][0]=map[i][m+1]='R';
            for(int j=1; j<=m; ++j){
                if(map[i][j]=='Y'){
                   q.push(node(i, j, 0));
                   map[i][j]='R';
                }
                map[0][j]=map[n+1][j]='R';
            }
        }
        if(!bfs())
           cout<<"-1"<<endl;
        while(!q.empty())  q.pop();
     }
    return 0;
/*
    将map[i][j]映射到 i*m+j的节点上,建立节点与节点之间的权值的关系!
    B->B的权值为1, E->B的权值为2, S<->...  R<->... 的权值为INF(也就是没有边存在) 
    在注意一点就是B->E的权值是 1,因为如果到B了,说明炮弹已经将墙轰掉了!
    
    建立好图之后,那么就是求源点到终点的最短的距离了!
    这里采用的spfa算法! 
*/

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define N 90010
#define INF 0x3f3f3f3f
using namespace std;
struct node{
   int to;
   int dist;
   node(){}
   
   node(int to, int dist){
     this->to=to;
     this->dist=dist;
   }
};
vector<node>g[N];
int vis[N], d[N];
char map[305][305];
int dir[4][2]={0, 1, 1, 0, -1, 0, 0, -1};
int ss, tt;
int n, m;
queue<int>q;
bool spfa(){
   q.push(ss);
   memset(vis, 0, sizeof(vis));
   vis[ss]=1;
   memset(d, 0x3f, sizeof(d));
   d[ss]=0;
   while(!q.empty()){
       int u=q.front(); q.pop();
       vis[u]=0;
       int len=g[u].size();
       for(int i=0; i<len; ++i){
           int v=g[u][i].to;
           if(d[v] > d[u] + g[u][i].dist){
                 d[v] = d[u] + g[u][i].dist;
                 
                 if(!vis[v]){
                 q.push(v);
                 vis[v]=1;     
              }
           }
       }
   }
   if(d[tt]==INF)  return false;
   return true;
}

int main(){
   while(cin>>n>>m && (n||m)){
      for(int i=0; i<n; ++i)
        cin>>map[i];
      for(int i=0; i<n; ++i)
         for(int j=0; j<m; ++j){
             int from=i*m+j;
             if(map[i][j]=='Y')  ss=from;
             else if(map[i][j]=='T') tt=from;
             else if(map[i][j]=='R' || map[i][j]=='S') continue;
             for(int k=0; k<4; ++k){
                 int x=i+dir[k][1];
                 int y=j+dir[k][0];
                 if(x<0 || x>=n || y<0 || y>=m)  continue;
                 if(map[x][y]=='R' || map[x][y]=='S') continue;
                 
                 int to = x*m+y, dist=1;
                 if(map[i][j]=='B' || map[x][y]=='B')  dist=2;
                 if(map[i][j]=='B' && map[x][y]!='B')  dist=1;
                 g[from].push_back(node(to, dist));
                 
             }
         }
       if(!spfa())
          cout<<"-1"<<endl;
       else cout<<d[tt]<<endl;
       for(int i=0; i<n*m; ++i)
          g[i].clear();
   }
   return 0;
}









本文转自 小眼儿 博客园博客,原文链接:http://www.cnblogs.com/hujunzheng/p/3910940.html,如需转载请自行联系原作者
目录
相关文章
|
算法
The kth great number(小根堆思想,模板题)
The kth great number(小根堆思想,模板题)
64 0
|
人工智能
poj 2299 Ultra-QuickSort 求逆序数 树状数组解法
所谓离散化,我们的了解就是对原数组排序,然后用所在位置的下标代替原数,这样我们就可以把数据范围缩小到1-500000,这个数组是开的下的。
66 0
|
开发框架 .NET
poj 3468 A Simple Problem with Integers线段树区间修改
题目意思很简单,有N个数,Q个操作, Q l r 表示查询从l到r 的和,C l r v 表示将从l到r 的值加上v,明显的线段树,不知道线段树的人肯定暴力,肯定超时,哈哈!!
37 0
HDU7050.Link with Limit(有向图tarjan找环)
HDU7050.Link with Limit(有向图tarjan找环)
156 0
|
人工智能 BI
Codeforces 1324 D-Pair of Topics(思维+二分 || 双指针)
Codeforces 1324 D-Pair of Topics(思维+二分 || 双指针)
146 0
UPC Graph (最小生成树 || 并查集+二分)
UPC Graph (最小生成树 || 并查集+二分)
105 0
Biggest Number深搜
You can start from any square, walk in the maze, and finally stop at some square. Each step, you may only walk into one of the four neighbouring squares (up, down, left, right) and you cannot walk into obstacles or walk into a square more than once.
125 0
Biggest Number深搜
|
Java
HDOJ/HDU 1297 Children’s Queue(推导~大数)
HDOJ/HDU 1297 Children’s Queue(推导~大数)
153 0