zoukankan      html  css  js  c++  java
  • [CODEVS1911] 孤岛营救问题(分层图最短路)

    传送门

    吐槽:神tm网络流。。。

    用持有的钥匙分层,状态压缩,用 2 进制表示持有的钥匙集合。

    dis[i][j][k] 表示持有的钥匙集合为 k,到达点 (i, j) 的最短路径。

    分层图的最短路听上去很玄乎,其实通过代码来看还是很好理解的。

    ——代码

     1 #include <queue>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <iostream>
     5 #define N 20
     6 #define min(x, y) ((x) < (y) ? (x) : (y))
     7 
     8 int n, m, p, ans = ~(1 << 31);
     9 int map[N][N][N][N], key[N][N], dis[N][N][1 << 11];
    10 int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};
    11 bool vis[N][N][1 << 11];
    12 
    13 struct node
    14 {
    15     int x, y, s;
    16     node(int x = 0, int y = 0, int s = 0) : x(x), y(y), s(s) {}
    17 };
    18 
    19 std::queue <node> q;
    20 
    21 inline int read()
    22 {
    23     int x = 0, f = 1;
    24     char ch = getchar();
    25     for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
    26     for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
    27     return x * f;
    28 }
    29 
    30 inline bool Acc(int x1, int y1, int x2, int y2, int s)
    31 {
    32     int need_key = map[x1][y1][x2][y2];
    33     if(!need_key) return 0;
    34     if(need_key == -1) return 1;
    35     return (s >> need_key - 1) & 1;
    36 }
    37 
    38 inline void spfa()
    39 {
    40     node now;
    41     int i, s, x, y;
    42     memset(dis, 127 / 3, sizeof(dis));
    43     dis[1][1][0] = 0;
    44     q.push(node(1, 1, 0));
    45     while(!q.empty())
    46     {
    47         now = q.front();
    48         q.pop();
    49         vis[now.x][now.y][now.s] = 0;
    50         for(i = 0; i < 4; i++)
    51         {
    52             x = now.x + dx[i];
    53             y = now.y + dy[i];
    54             s = now.s | key[x][y];
    55             if(!x || x > n || !y || y > m) continue;
    56             if(Acc(now.x, now.y, x, y, now.s))
    57                 if(dis[x][y][s] > dis[now.x][now.y][now.s] + 1)
    58                 {
    59                     dis[x][y][s] = dis[now.x][now.y][now.s] + 1;
    60                     if(!vis[x][y][s])
    61                     {
    62                         vis[x][y][s] = 1;
    63                         q.push(node(x, y, s));
    64                     }
    65                 }    
    66         }
    67     }
    68 }
    69 
    70 int main()
    71 {
    72     int i, j, a, b, c, d, x, y, z, doors, keys;
    73     n = read();
    74     m = read();
    75     p = read();
    76     doors = read();
    77     memset(map, -1, sizeof(map));
    78     for(i = 1; i <= doors; i++)
    79     {
    80         a = read();
    81         b = read();
    82         c = read();
    83         d = read();
    84         map[a][b][c][d] = map[c][d][a][b] = read();
    85     }
    86     keys = read();
    87     for(i = 1; i <= keys; i++)
    88     {
    89         x = read();
    90         y = read();
    91         z = read();
    92         key[x][y] |= 1 << z - 1;
    93     }
    94     spfa();
    95     for(i = 0; i < (1 << 11); i++) ans = min(ans, dis[n][m][i]);
    96     if(ans == 707406378) ans = -1;
    97     printf("%d
    ", ans);
    98     return 0;
    99 }
    View Code
  • 相关阅读:
    ASP.NET 3.5 的 ListView 控件与 CSS Friendly
    从 Adobe SHARE 说到 Silverlight 的 XPS 支持
    编写 iPhone Friendly 的 Web 应用程序 (Part 5 交互入门)
    初为项目经理
    管理的最高境界不是完美
    url传递中文的解决方案总结
    我想跟什么样的人合作
    异步Socket通信总结
    让机器自动支持中文文件名
    Socket基本编程
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/7001446.html
Copyright © 2011-2022 走看看