「hdu 4845 」拯救大兵瑞恩(状态压缩bfs | 分层图思想)

Posted cminus

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「hdu 4845 」拯救大兵瑞恩(状态压缩bfs | 分层图思想)相关的知识,希望对你有一定的参考价值。

首先关于分层图思想详见2004的这个论文

https://wenku.baidu.com/view/dc57f205cc175527072208ad.html

这道题可以用状态压缩,我们对于每一把钥匙的状态只有两种,获得了或者没有获得,然后就可以用二进制方法表示,例如一共有5把钥匙,我们如果用二进制数01001表示当前状态,就意味着我们已经拥有了第一类钥匙,第四类钥匙(从右往左看),然后我们就可以把此时的状态压缩为一个int了,节省了很多的空间,具体的操作就用位运算实现。

然后就是简单粗暴的dfs过程。

不过有几个点需要注意

① 要加反边。

② 一个位置可能有多个钥匙,注意要用位与运算。

下面给出代码。

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <queue>
 4 #include <cstring>
 5 using namespace std;
 6 const int N = 20;
 7  
 8 struct Node{
 9     int x, y, step, state;
10 };
11 int n, m, p, t, tt, map[N][N][N][N], key[N][N], vis[N][N][1 << 11];
12 int py[4][2] = {{0, 1}, {0, -1}, {-1, 0}, {1, 0}};
13  
14 inline int bfs(){
15     queue < Node > q;
16     q.push((Node){1, 1, 0, key[1][1]});
17     while(!q.empty()){
18         Node u = q.front(); q.pop();
19         if (u.x == n && u.y == m)    return u.step; 
20         for (int i = 0; i < 4; i++){
21             int x = u.x + py[i][0];
22             int y = u.y + py[i][1];
23             if (x > 0 && x <= n && y > 0 && y <= m)
24                if (!map[u.x][u.y][x][y]) continue;
25                else if((map[u.x][u.y][x][y] == -1) || (1 << (map[u.x][u.y][x][y] - 1)) & u.state){
26                     int states = u.state | key[x][y];
27                     if (!vis[x][y][states]){
28                         q.push((Node){x, y, u.step + 1, states});
29                         vis[x][y][states] = 1;
30                     }
31                }
32         }
33     }
34     return -1;
35 }
36      
37                      
38         
39 int main(){
40     scanf("%d %d %d",&n, &m, &p);
41     scanf("%d", &t);
42     memset(map, -1, sizeof(map));
43     for (int i = 0; i < t; i++){
44         int a, b, c, d, e;
45         scanf("%d %d %d %d %d", &a, &b, &c, &d, &e);
46         map[a][b][c][d] = map[c][d][a][b] = e;
47     }
48     scanf("%d", &tt);
49     for (int i = 0; i < tt; i++){
50         int a, b, c;
51         scanf("%d %d %d", &a, &b, &c);
52         key[a][b] |= (1 << (c - 1));
53     }
54     printf("%d", bfs());
55     return 0;
56 }
57      
58  
59 /**************************************************************
60     Problem: 1784
61     User: cminus
62     Language: C++
63     Result: Accepted
64     Time:0 ms
65     Memory:4896 kb
66 ****************************************************************/

 

以上是关于「hdu 4845 」拯救大兵瑞恩(状态压缩bfs | 分层图思想)的主要内容,如果未能解决你的问题,请参考以下文章

拯救大兵瑞恩 HDU - 4845(状压bfs || 分层最短路)

HDU4845(SummerTrainingDay02-C 状态压缩bfs)

拯救大兵瑞恩 HDU - 4845 (分层)

拯救大兵瑞恩 HDU - 4845 (分层)

hdu 4845 状压bfs(分层思想)

AcWing1131 拯救大兵瑞恩(最短路)