HDU 1072 Nightmare

最短路一般使用广度优先的方法最好。

一道可以改变搜索深度的题目,一开始想用深搜+广搜每次扩展可行路径的方式加大搜索有效性,但是写不出来,也不知道可不可行,可能复杂化了

1.每次去搜索节点时,。除了可设置点‘4’外,其它不记录已经搜索过,搜索过的节点每次判断当前可以继续使用的时间是否更优。如果更优则加入队列。

  否则:

2.如果原队列里的节点已经可以达到要求,那么新添加的节点一定不是最优,而且不会首先出队,故不会影响最优结果

3.如果队列的节点不满足那么新更新的节点可能可以达到最优值。

4.规模小,可以重复搜索是关键,否则算法要求更高。

#include <stdio.h>
#include <queue>
using namespace std;

int t ,n , m ,sx,sy;

int maz[11][11],stp[11][11] , tim[11][11];
const int dx[] = {1,0,-1,0};
const int dy[] = {0,1,0,-1};

int bfs(){
    queue<int> q;
    memset(tim , 0 , sizeof(tim));
    memset(stp , 0 , sizeof(stp));
    q.push(sx*m+sy);
    stp[sx][sy] = 0;
    tim[sx][sy] = 6;
    while(!q.empty()){
        int tn = q.front();
        q.pop();
        int x = tn / m , y = tn % m;
        if(maz[x][y]==3) return stp[x][y];
        
        for(int i=0;i<4;i++){
            int nx = x + dx[i],ny=y+dy[i];
            if(nx >=0 && nx < n && ny >= 0 && ny < m && 
                tim[x][y] > 0 && maz[nx][ny]!=0){
                
                int _t;
                if(maz[nx][ny] == 4 && tim[x][y]-1 > 0) _t=6;
                else _t = tim[x][y]-1;
                
                if(_t <= 0) continue;
                
                if(stp[nx][ny]>0){
                    if(tim[nx][ny] >= _t) continue;
                }
                tim[nx][ny]=_t;
                stp[nx][ny] = stp[x][y] + 1;
                q.push(nx * m + ny);
            }
        }
    }
    return -1;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d %d",&n,&m);
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                scanf("%d",&maz[i][j]);
                if(maz[i][j]==2) sx=i,sy=j;
            }
        }
        printf("%d\n" , (t = bfs()) > 0 ? t : -1);
    }
    return 0;
}
View Code

 

posted on 2013-12-01 14:09  从此以后  阅读(257)  评论(0编辑  收藏  举报