用四维数组记录墙
同一个地方可能有多把钥匙
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <cmath>
using namespace std;
#include <queue>
#include <stack>
#include <vector>
#include <deque>
#define cler(arr, val) memset(arr, val, sizeof(arr))
typedef long long LL;
const int MAXN = 100200;
const int MAXM = 6000010;
const int INF = 0x3f3f3f3f;
const int mod = 1000000007;
int xx[4]={1,-1,0,0};
int yy[4]={0,0,1,-1};
bool wall[51][51][51][51];
int mp[51][51][51][51];
int key[51][51];
int n,m,p;
bool vis[51][51][1<<11];
struct node
{
int key;
int x,y;
int step;
};
queue<node>q;
int bfs(int x,int y)
{
cler(vis,false);
node star,end;
star.x=x,star.y=y;
star.step=star.key=0;
while(!q.empty()) q.pop();
q.push(star);
vis[x][y][0]=true;
while(!q.empty())
{
star=q.front();
q.pop();
x=star.x,y=star.y;
for(int i=0;i<4;i++)
{
int dx=x+xx[i],dy=y+yy[i];
end=star;
if(mp[x][y][dx][dy]!=0)
{
if((end.key&1<<(mp[x][y][dx][dy]-1))==0)
continue;
}
if(!wall[x][y][dx][dy]&&!vis[dx][dy][star.key]&&dx>=1&&dx<=n&&dy>=1&&dy<=m)
{
vis[dx][dy][star.key]=true;
if(dx==n&&dy==m)
return star.step+1;
end.x=dx,end.y=dy,end.step=star.step+1;
if(key[dx][dy])
for(int j=0;j<p;j++)
if(key[dx][dy]&(1<<j))
end.key|=(1<<j);
q.push(end);
}
}
}
return -1;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif
while(~scanf("%d%d%d",&n,&m,&p))
{
cler(wall,false);
cler(mp,0);
cler(key,0);
int z,x1,x2,y1,y2,t;
scanf("%d",&z);
for(int i=0;i<z;i++)
{
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&t);
if(t==0)
wall[x1][y1][x2][y2]=wall[x2][y2][x1][y1]=true;
else mp[x1][y1][x2][y2]=mp[x2][y2][x1][y1]=t;
}
scanf("%d",&z);
for(int i=0;i<z;i++)
{
scanf("%d%d%d",&x1,&y1,&t);
key[x1][y1]|=(1<<(t-1));
}
cout<<bfs(1,1)<<endl;
}
return 0;
}