首页 > 代码库 > hdu 1072 广搜

hdu 1072 广搜

广搜,用到优先队列,跟hdu1026差不多。但须注意几个问题:

1、可以往回走,由于可以重设时间,有时需要拐弯去“加油”,但可重设时间的结点不能在让它有机会被重走,不然就进入死循环了。

2、队列每次弹出的都是用时最少的,需要自定义排序

#include <iostream>#include <queue>using namespace std;int map[9][9];int n,m;int dir[4][2]={0,1, 1,0, -1,0, 0,-1};struct Node{    int x,y;    int time;    int step;//剩余的步数    bool operator<(const Node &a) const{        return a.time<time;    }};int bfs(int x, int y, int end_x, int end_y){    priority_queue<Node>que;    struct Node start;    start.x=x;    start.y=y;    start.time=0;    start.step=6;    que.push(start);    while(!que.empty())    {        struct Node cur=que.top();        que.pop();        if(cur.step==0) continue;//时间到了,结束搜索        if(cur.step>=1 && cur.x==end_x && cur.y==end_y) return cur.time;//注意要保证剩余时间大于1        for(int i=0; i<4; i++){            int xtmp=cur.x+dir[i][0];            int ytmp=cur.y+dir[i][1];            if(map[xtmp][ytmp]==0 || xtmp<0 || xtmp>=n || ytmp<0 ||ytmp>=m) continue;            struct Node next;            next.x=xtmp;            next.y=ytmp;            next.time=cur.time+1;            next.step=cur.step-1;            if(map[xtmp][ytmp]==4 && next.step>=1){//注意重设时间的条件                        next.step=6;                map[xtmp][ytmp]=0;            }            que.push(next);        }    }    return -1;}int main(){    int t, i,j, start_x, start_y, end_x, end_y;    cin>>t;    while(t--)    {        scanf("%d%d", &n, &m);        for(i=0; i<n; i++){            for(j=0; j<m; j++){                scanf("%d", &map[i][j]);                if(map[i][j]==2){                    start_x=i;                    start_y=j;                } else if(map[i][j]==3){                    end_x=i;                    end_y=j;                }            }        }        int result=bfs(start_x, start_y, end_x, end_y);        cout<<result<<endl;    }    return 0;}

一直都是无题解不AC,这次由于做完hdu 1026没多久,很快想到解决的办法,但是在细节处理上还是用了很长的时间。加油!

hdu 1072 广搜