好吧,说是网络流24题,但是我首先想到的是状压搜索
第一次写状压搜索,竟然一次过,挺惊讶的。
对于钥匙, 因为只有 10 把, 所以, 我们可以把一个时刻有多少把钥匙,用一个数来表示,比如 0 就表示此时身上一把钥匙都没有, 5 的二进制是 101 从低位开始, 表示他有钥匙 1 和 3
这样就可以开心的搜索了
//代码中 从低位开始, 第2表示 钥匙1 第3表示 钥匙2
#include <bits/stdc++.h>
const int maxn = 12;
using namespace std;
typedef long long ll;
int xiang[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
struct note
{
int x, y, z; //x y 坐标 z 拥有的钥匙状态
int bu; //步数
note() {}
note(int x1, int y1, int z1, int bu1)
{
x = x1, y = y1, z = z1, bu = bu1;
}
} temp;
int suo[maxn][maxn][maxn][maxn]; //suo[i][j][k][l] (i,j) --> (k, l) 有某类型的锁
int yao[maxn][maxn][maxn]; //yao[i][j][k] (i,j) 有 yao[i][j][0]把钥匙 一个单元格有可能有多把钥匙
bool vis[maxn][maxn][(1 << 11)]; //标记 vis[i][j][x] x 是 (i,j)的钥匙状态
int n, m, p, k;
void bfs()
{
temp.x = temp.y = 1;
temp.bu = temp.z = 0;
for (int i = 1; i <= yao[1][1][0]; i++) // 初始位置(1,1)可能有钥匙
temp.z = temp.z | (1 << yao[1][1][i]);
// printf("%d
", temp.z);
vis[1][1][temp.z] = true;
queue<note> q;
q.push(temp);
int ans = -1;
while (!q.empty())
{
temp = q.front();
q.pop();
if (temp.x == n && temp.y == m)
{
ans = temp.bu;
break;
}
for (int i = 0; i < 4; i++)
{
int tx = temp.x + xiang[i][0];
int ty = temp.y + xiang[i][1];
if (tx < 1 || ty < 1 || tx > n || ty > m || suo[temp.x][temp.y][tx][ty] == -1) //越界 本来就过不去
continue;
if (suo[temp.x][temp.y][tx][ty] != 0 && !(temp.z & (1 << suo[temp.x][temp.y][tx][ty]))) //有锁 没钥匙
continue;
if (vis[tx][ty][temp.z] == true) //这个坐标,同样的钥匙状态已经去过了
continue;
vis[tx][ty][temp.z] = true; //标记去过
int tz = temp.z;
for (int i = 1; i <= yao[tx][ty][0]; i++)
{
tz = tz | (1 << yao[tx][ty][i]);
}
vis[tx][ty][tz] = true; //标记去过 将前后钥匙状态都标记,能减少搜索量
q.push(note(tx, ty, tz, temp.bu + 1));
}
}
printf("%d
", ans);
}
int main()
{
scanf("%d%d%d", &n, &m, &p);
scanf("%d", &k);
while (k--)
{
int x1, y1, x2, y2, g;
scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &g);
if (g == 0)
g = -1;
suo[x1][y1][x2][y2] = g; // (x1, y1) ---> (x2, y2) 的路上有一个 g 类型的锁 g = -1 表示不通
suo[x2][y2][x1][y1] = g;
}
scanf("%d", &k);
while (k--)
{
int x, y, q;
scanf("%d%d%d", &x, &y, &q);
yao[x][y][0]++;
yao[x][y][yao[x][y][0]] = q;
}
bfs();
return 0;
}