POJ2312坦克大战(优先队列bfs)

简单的BFS搜索题,之前直接用的队列wa了一发,仔细想想还是需要用优先队列的。 因为在打坏砖块之后,当前节点的step++了, 因为在代码中打坏砖块然后移动到砖块上,这两个操作我们给合并到了一起,并不属于同一层节点,因此BFS的最短路性质就被破坏了,因此用优先队列,始终让头结点是step最小的那个就行了。有点像QUT校赛的那一题。

【代码】

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define M 30
using namespace std;
char s[310][310];
bool vis[310][310];
struct node{
    int x,y;
    int step;
    node(int x = 0,int y =0 ,int step= 0):x(x),y(y),step(step){};
    bool operator < (const node &a)const{
        return step > a.step;
    }
}st,ed;
int dx[4] = {0,0,-1,1};
int dy[4] = {1,-1,0,0};int n,m;
int bfs(){
    priority_queue<node>Q;
    Q.push(st);
    memset(vis,0,sizeof(vis));
    while(!Q.empty()){
        node now = Q.top(); Q.pop();
        node nt;
        for(int i=0;i<4;i++){
             nt.x = now.x + dx[i];
             nt.y = now.y + dy[i];
            nt.step = now.step + 1;
            if(nt.x >=0 && nt.x < n && nt.y>=0 && nt.y<m
               &&!vis[nt.x][nt.y] ){
                if(s[nt.x][nt.y] == 'E'){
                    vis[nt.x][nt.y] = 1;
                    Q.push(nt);
                }
                else if(s[nt.x][nt.y] == 'T'){
                    return nt.step;
                }
                else if(s[nt.x][nt.y] == 'B'){
                    nt.step++; // 队列中的step不同
                                //因而优先队列是正解
                    vis[nt.x][nt.y] = 1;
                    Q.push(nt);
                }
            }
        }
    }
    return -1;
}
int main(){

    while(scanf("%d%d",&n,&m)!=EOF &&(n || m)){
        for(int i=0;i<n;i++) scanf("%s",s[i]);
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(s[i][j] == 'Y')
                    st.x = i,st.y = j;
                else if(s[i][j] == 'T')
                    ed.x = i,ed.y = j;
            }
        }
        st.step = 0;
        int ans = bfs();
        printf("%d\n",ans);
    }


    return 0;
}


你可能感兴趣的:(搜索,图论)