hdu 5094 Maze (BFS+状压)

题意:

n*m的迷宫。多多要从(1,1)到达(n,m)。每移动一步消耗1秒。有P种钥匙。

有K个门或墙。给出K个信息:x1,y1,x2,y2,gi    含义是(x1,y1)与(x2,y2)之间有gi。gi=0:墙   1,2,3.... :第1种门,第2种门,第3种门.....

有S把钥匙。给出S个信息:x1,y1,qi    含义是位置(x1,y1)上有一把第qi种的钥匙。

问多多最少花多少秒到达(n,m)。若无法到达输出-1。

数据范围:

(1<= n, m <=50, 0<= p <=10).

(0<= k <=500)

(0<= S <=50)

思路:

n,m很小。经典BFS+状压,

注意的是,同一位置上可能有多把钥匙。(注意到S的范围是S<=50)

还有一个要注意:位运算式子的处理要仔细。(最好测试一下)。

代码:

struct node{
    int x,s;
    node(int _x,int _s){
        x=_x, s=_s;
    }
};

int n,m,p,k,S;
int xx1,yy1,xx2,yy2,gi;
int mazeG[55][55][55][55], mazeK[55][55][15];
int dp[55][55][1050];



int bfs(){
    queue<node> q;
    mem(dp,-1);
    int s=0;
    rep(i,1,p) if(mazeK[1][1][i]>0) s|=(1<<(i-1));
    q.push(node(101,s));
    dp[1][1][s]=0;
    if(1==n && 1==m) return 0;
    while(!q.empty()){
        node f=q.front();  q.pop();
        rep(i,0,3){
            int nx=f.x/100+uu[i], ny=f.x%100+vv[i];
            int _s=f.s;
            if(nx<=0||ny<=0||nx>n||ny>m||(mazeG[f.x/100][f.x%100][nx][ny]==0)) continue; //overBound or meet the wall.

            if(mazeG[f.x/100][f.x%100][nx][ny]>0){
                int yes=_s&(1<<(mazeG[f.x/100][f.x%100][nx][ny]-1));
                if(yes==0) continue; //don't have corresponding key.
            }
            int ns=_s;
            rep(i,1,p) if(mazeK[nx][ny][i]) ns|=(1<<(i-1));
            if(dp[nx][ny][ns]!=-1) continue;
            q.push(node(nx*100+ny,ns));
            dp[nx][ny][ns]=dp[f.x/100][f.x%100][_s]+1;
            if(nx==n&&ny==m) return dp[nx][ny][ns];
        }
    }
    return -1;
}


int main(){
    while(scanf("%d%d%d",&n,&m,&p)!=EOF){ //p kinds of doors
        scanf("%d",&k);
        mem(mazeG,-1); //doors or walls
        mem(mazeK,false); //keys
        rep(i,1,k){
            scanf("%d%d%d%d%d",&xx1,&yy1,&xx2,&yy2,&gi);
            mazeG[xx1][yy1][xx2][yy2]=gi;
            mazeG[xx2][yy2][xx1][yy1]=gi;
        }
        scanf("%d",&S); // S keys
        rep(i,1,S){
            scanf("%d%d%d",&xx1,&yy1,&gi);
            mazeK[xx1][yy1][gi]=true;
        }
        printf("%d
",bfs());
    }
}
原文地址:https://www.cnblogs.com/fish7/p/4085896.html