zoukankan      html  css  js  c++  java
  • [HDOJ5094] Maze (记忆化搜索,BFS,状态压缩)

    题目链接:https://vjudge.net/problem/HDU-5094

    题意:很典型的迷宫寻路,但是点与点之间有障碍或者门,每个点有钥匙。与其他题不同的地方是障碍不是单纯的某一个点不可以走,而是两点之间。求从一点出发到另一点最短路。

    很简单,用G[][][][]存两个点之间的障碍(图大了其实也可以用unordered_map<pii,pii>)。钥匙顶多10把,用位压记录钥匙状态,bfs的时候队内节点维护当前点、钥匙拥有情况、最短路。直接记忆化搞就是了。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int maxn = 55;
     5 const int dx[5] = {0, 0, 1, -1};
     6 const int dy[5] = {1, -1, 0, 0};
     7 typedef struct Node {
     8     int x, y, k;
     9     Node() {}
    10     Node(int x, int y, int k) : 
    11       x(x), y(y), k(k) {}
    12 }Node;
    13 typedef pair<Node, int> pni;
    14 
    15 int G[maxn][maxn][maxn][maxn];
    16 int key[maxn][maxn];
    17 int dp[1<<10][maxn][maxn];
    18 int n, m, p, k, g;
    19 int x1, y1, x2, y2;
    20 
    21 bool ok(int x, int y) {
    22     return x >= 1 && x <= n && y >= 1 && y <= m;
    23 }
    24 
    25 int bfs() {
    26     queue<pni> q;
    27     memset(dp, -1, sizeof(dp));
    28     q.push(pni(Node(1, 1, 0), 0));
    29     dp[0][1][1] = 0;
    30     while(!q.empty()) {
    31         pni tmp = q.front(); q.pop();
    32         x1 = tmp.first.x, y1 = tmp.first.y; k = tmp.first.k;
    33         if(x1 == n && y1 == m) return tmp.second;
    34         for(int i = 0; i < 4; i++) {
    35             x2 = x1 + dx[i];
    36             y2 = y1 + dy[i];
    37             if(!ok(x2, y2) || !G[x1][y1][x2][y2]) continue;
    38             if(G[x1][y1][x2][y2] != -1) {
    39                 if(!((1 << (G[x1][y1][x2][y2]) - 1) & k)) continue;
    40             }
    41             int st = k | key[x2][y2];
    42             if(dp[st][x2][y2] == -1) {
    43                 dp[st][x2][y2] = tmp.second + 1;
    44                 q.push(pni(Node(x2, y2, st), tmp.second+1));
    45             }
    46         }
    47     }
    48     return -1;
    49 }
    50 
    51 int main() {
    52     // freopen("in", "r", stdin);
    53     while(~scanf("%d%d%d",&n,&m,&p)) {
    54         scanf("%d", &k);
    55         memset(G, -1, sizeof(G));
    56         memset(key, 0, sizeof(key));
    57         for(int i = 0; i < k; i++) {
    58             scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&g);
    59             G[x1][y1][x2][y2] = G[x2][y2][x1][y1] = g;
    60         }
    61         scanf("%d", &k);
    62         for(int i = 0; i < k; i++) {
    63             scanf("%d%d%d",&x1,&y1,&g);
    64             key[x1][y1] |= (1 << (g - 1));
    65         }
    66         cout << bfs() << endl;
    67     }
    68     return 0;
    69 }
  • 相关阅读:
    Trapping Rain Water
    Construct Binary Tree from Preorder and Inorder Traversal
    Flatten Binary Tree to Linked List
    Permutations II
    Unique Paths II
    Path Sum II
    Unique Binary Search Trees II
    evdev module-----uinput.py
    evdev module-----events.py
    evdev module-----device.py
  • 原文地址:https://www.cnblogs.com/kirai/p/6785318.html
Copyright © 2011-2022 走看看