状压,BFS
https://www.luogu.com.cn/problem/P4011

题意

有一个 \(n*m\) 的迷宫,每个格子到相邻格子可能有墙,也可能有门,钥匙会散落在迷宫中的一些格子内,问从 \((1,1)\) 走到 \((n,m)\) 的最短路径长度

Tutorial

这个网络流24题是谁搞出来的东西,两题都不用网络流写,甚至网络流写法看上去有些蠢。
普通bfs,没啥好说的。

点击查看代码
#include <bits/stdc++.h>
typedef long long ll;
#define endl '\n'
#define P pair<int, int>
#define eps 1e-8
#define IOS                  \
    ios::sync_with_stdio(0); \
    cin.tie(0);              \
    cout.tie(0);
using namespace std;

const int N = 15 + 5;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
typedef long long ll;
struct node {
    int x, y, step, st;
    node(int _x, int _y, int _step, int _st) {
        x = _x, y = _y, step = _step, st = _st;
    }
};
int dx[] = {0, 1, 0, -1};
int dy[] = {1, 0, -1, 0};
int n, m, p;
bool vis[N][N][1 << 14 + 6];
int mp[N][N][N][N];
vector<int> key[N][N];
inline bool check(int x, int y, int s) {
    return 0 < x && x <= n && 0 < y && y <= m;
}
int solve() {
    queue<node> q;
    int sst = 0;
    for (int i : key[1][1])
        sst |= (1 << (i - 1));
    q.emplace(1, 1, sst, 0);
    vis[1][1][sst] = 1;
    while (q.size()) {
        node o = q.front();
        q.pop();
        if (o.x == n && o.y == m)
            return o.step;
        // cout<<"->"<<o.x<<" "<<o.y<<endl;
        for (int dir = 0; dir < 4; dir++) {
            int dx = o.x + ::dx[dir], dy = o.y + ::dy[dir];
            if (!check(dx, dy, o.st))
                continue;
            int walk = mp[o.x][o.y][dx][dy];
            if (walk && !((1 << (walk - 1)) & o.st))
                continue;
            int ds = o.st;
            for (auto i : key[dx][dy]) {
                ds |= (1 << (i - 1));
            }
            if (vis[dx][dy][ds])
                continue;
            vis[dx][dy][ds] = 1;
            q.emplace(dx, dy, o.step + 1, ds);
        }
    }
    return -1;
}
int main() {
    cin >> n >> m >> p;
    // cout << "----\n";
    cin >> p;
    for (int i = 0, x1, y1, x2, y2, g; i < p; i++) {
        cin >> x1 >> y1 >> x2 >> y2 >> g;
        mp[x1][y1][x2][y2] = mp[x2][y2][x1][y1] = g;
        if (!g)
            mp[x1][y1][x2][y2] = mp[x2][y2][x1][y1] = -1;
    }
    int s;
    cin >> s;
    for (int i = 0, x, y, g; i < s; i++) {
        cin >> x >> y >> g;
        key[x][y].push_back(g);
    }
    int ans = solve();
    cout << ans << endl;
}