【状态压缩&&bfs】HDU - 5094

Step1 Problem:

有一个你n*m的地图,里面有p种类型的门。
p == 0的时候,该门是打不开的。
p != 0的时候,该门需要p这把钥匙打开。
告诉你哪些点移动到哪些点,有门。
告诉你哪些点有钥匙。
问你从(1, 1) 走到 (n, n) 最少需要走多少步(一个点 可以 走上下左右四个方向)。
例:
输入:
4 4 9
9
1 2 1 3 2
1 2 2 2 0
2 1 2 2 0
2 1 3 1 0
2 3 3 3 0
2 4 3 4 1
3 2 3 3 0
3 3 4 3 0
4 3 4 4 0
2
2 1 2
4 2 1
输出:
14
数据范围:
1<=n, m <= 50, 0 <= p <= 10

Step2 Ideas:

因为钥匙种类很少,可以状态压缩,拥有哪些钥匙种类。
状态vis[u][v][now] //到达(u, v)这个点,当前钥匙的状态now,所需的最少步骤。
然后BFS即可

Step3 Code:

#include<bits/stdc++.h>
using namespace std;
struct node
{
    int u, v, now;
};
const int N = 55;
int vis[N][N][1<<11];
int td[N][N][N][N], key[N][N], n, m;
int x[5] = {1, -1, 0, 0};
int y[5] = {0, 0, 1, -1};
bool judge(int ux, int vy)
{
    if(ux >= 1 && ux <= n && vy >= 1 && vy <= m) return 1;
    else return 0;
}
int bfs()
{
    queue<node> q;
    q.push((node){1, 1, key[1][1]});
    memset(vis, 0, sizeof(vis));
    vis[1][1][key[1][1]] = 1;
    while(!q.empty())
    {
        node t = q.front(); q.pop();
        int u = t.u, v = t.v, now = t.now;
        if(u == n && v == m) return vis[u][v][now] - 1;
        for(int i = 0; i < 4; i++)
        {
            int ux = t.u + x[i], vy = t.v + y[i];
            int o = t.now | key[ux][vy];
            if(judge(ux, vy) && (td[u][v][ux][vy]==-1 || ((1<<(td[u][v][ux][vy]-1))&now)))
            {
                if(!vis[ux][vy][o])
                {
                    vis[ux][vy][o] = vis[u][v][now] + 1;
                    q.push((node){ux, vy, o});
                }
            }

        }
    }
    return -1;
}
int main()
{
    int p, x1, y1, x2, y2, ok, k;
    while(~scanf("%d %d %d", &n, &m, &p))
    {
        scanf("%d", &k);
        memset(td, -1, sizeof(td));
        while(k--)
        {
            scanf("%d %d %d %d %d", &x1, &y1, &x2, &y2, &ok);
            td[x1][y1][x2][y2] = td[x2][y2][x1][y1] = ok;
        }
        scanf("%d", &k);
        memset(key, 0, sizeof(key));
        while(k--)
        {
            scanf("%d %d %d", &x1, &y1, &ok);
            key[x1][y1] |= (1<<(ok-1));
        }
        printf("%d\n", bfs());
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/bbbbswbq/article/details/80164298
今日推荐