HDU 5094 Maze & HDU 4845 拯救大兵瑞恩 (BFS + 状压)

来源:互联网 发布:91手机助手mac版 编辑:程序博客网 时间:2024/05/16 00:52

题意:给你一个n*m的迷宫,地图中有一些障碍不能走,还有p种门,要过门首先得拿到跟这扇门同类型的钥匙。

问从(1,1)到(n,m)最短时间。(1<= n, m <=50, 0<= p <=10)


思路:没有门的时候都会做,一个bfs就行,现在只不过是多了门这种情况。

解决办法:

book[x][y][sta] 表示(x, y)这个点在sta状态下是否已经走过,sta表示拥有钥匙情况。

bar[x1][y1][x2][y2] 表示(x1, y1)到(y1, y2)是否有墙

sth[x1][y1][x2][y2] 表示(x1, y1)到(x2, y2)存在哪种门,0表示没有

key[x][y] 表示(x, y)处有什么钥匙

有了这些处理,再去做bfs就可以了。

注意有些点可能有多个钥匙;墙和门是双向的。


代码:

#include<iostream>#include<cstdio>#include<cstring>#include<queue>using namespace std;const int maxn = 51;const int maxm = 11;bool book[maxn][maxn][1<<maxm];bool bar[maxn][maxn][maxn][maxn];int sth[maxn][maxn][maxn][maxn];int key[maxn][maxn];int n, m, p, k; //k men\qiang, p kindstruct node{    int x, y, t, k;    node() {}    node(int xx, int yy, int tt, int kk): x(xx), y(yy), t(tt), k(kk) {}};int bfs(){    int Next[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};    memset(book, 0, sizeof(book));    queue<node> q;    int tmp = 0;    if(key[1][1])        tmp |= key[1][1];    q.push(node(1, 1, 0, tmp));    book[1][1][tmp] = 1;    while(!q.empty())    {        node u = q.front(); q.pop();        int x = u.x, y = u.y, t = u.t, k = u.k;        if(x == n && y == m) return t;        for(int i = 0; i < 4; i++)        {            int tx = x+Next[i][0];            int ty = y+Next[i][1];            if(tx >= 1 && ty >= 1 && tx <= n && ty <= m && !bar[x][y][tx][ty] && !book[tx][ty][k])            {                if(!sth[x][y][tx][ty] || (k>>(sth[x][y][tx][ty]-1))&1)                {                    book[tx][ty][k] = 1;                    book[tx][ty][k|key[tx][ty]] = 1;                    q.push(node(tx, ty, t+1, k|key[tx][ty]));                }            }        }    }    return -1;}int main(void){    while(cin >> n >> m >> p)    {        memset(key, 0, sizeof(key));        memset(bar, 0, sizeof(bar));        memset(sth, 0, sizeof(sth));        scanf("%d", &k);        for(int i = 1; i <= k; i++)        {            int x1, y1, x2, y2, z;            scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &z);            if(!z) bar[x1][y1][x2][y2] = bar[x2][y2][x1][y1] = 1;            else sth[x1][y1][x2][y2] = sth[x2][y2][x1][y1] = z;        }        scanf("%d", &k);        for(int i = 1; i <= k; i++)        {            int x, y, z;            scanf("%d%d%d", &x, &y, &z);            key[x][y] |= (1<<(z-1));        }        printf("%d\n", bfs());    }    return 0;}


原创粉丝点击