这道题其实是一道状态压缩的spfa,把每个状态压缩成一个二进制数。
最后判断答案的时候要注意,因为最快到达的状态不一定是钥匙最多的那个,所以写个循环判断一下
#include <bits/stdc++.h>
#define ll long long
using namespace std;
struct node
{
int x,y,state;
};
int gate[1001][1001];
int vis[101][101][101];
int key[1001][1001];
int f[101][101][1<<10];
int id[1001][1001];
int dx[4] = {0,1,0,-1};
int dy[4] = {1,0,-1,0};
const int INF = 0x3f3f3f3f;
int n,m,p;
bool check(int x1,int x2,int y1,int y2,int sta)
{
int need = gate[id[x1][y1]][id[x2][y2]];
if(!need) return 0;
if(need == -1) return 1;
return (sta >> need) & 1;
}
void bfs()
{
node a,now;
a.x = 1;
a.y =1;
a.state = 0;
queue<node> q;
q.push(a);
f[1][1][0] = 0;
while(!q.empty())
{
now = q.front();q.pop();
vis[now.x][now.y][now.state] = 0;
int sta = now.state;
if(key[now.x][now.y]) sta |= key[now.x][now.y];
for(int i = 0;i<4;i++)
{
int x = now.x + dx[i];
int y = now.y + dy[i];
if(!x || !y || x > n || y > m) continue;
if(check(now.x,x,now.y,y,sta))
{
if(f[x][y][sta] > f[now.x][now.y][now.state] + 1)
{
f[x][y][sta] = f[now.x][now.y][now.state]+1;
if(!vis[x][y][sta])
{
vis[x][y][sta] = 1;
q.push({x,y,sta});
}
}
}
}
}
}
int main()
{
scanf("%d%d%d",&n,&m,&p);
for(int i = 1; i<=n; i++)
{
for(int j =1; j<=m; j++)
{
id[i][j] = (i-1)*m + j;
}
}
int k;
scanf("%d",&k);
int a,b,c,d,q;
memset(gate,-1,sizeof(gate));
memset(f,0x7f,sizeof(f));
while(k--)
{
scanf("%d%d%d%d%d",&a,&b,&c,&d,&q);
gate[id[a][b]][id[c][d]] = q;
gate[id[c][d]][id[a][b]] = q;
}
scanf("%d",&q);
int sum = 0;
while(q--)
{
scanf("%d%d%d",&a,&b,&c);
key[a][b] |= (1<<c);
}
bfs();
int ans = INF;
for(int i = 0;i<(1<<10);i++)
{
ans = min(ans,f[n][m][i]);
}
if(ans >= INF) ans = -1;
printf("%d\n",ans);
return 0;
}