node里面多开一维,表示拥有钥匙的状态。
标记数组多开一维,vis[i][j][k]表示第i行第j列拥有钥匙的状态。
剩下的就是BFS。
这个题一个格子里面有可能有很多把钥匙,这是一个坑点,wa了2发。
#include<cstdio>
#include<map>
#include<queue>
#include<cstring>
using namespace std;
const int bit = 1<<12;
int n,m,p,k,numk;
int bmap[55][55];
struct node{
int x;
int y;
int step;
int key;
node(int a,int b,int c,int d):x(a),y(b),step(c),key(d){}
};
map<pair<int,int>,int> door;
int vis[51][51][(1<<12)+5];
int sumkey[55][55];
int dir[4][2] = {1,0,-1,0,0,1,0,-1};
void bfs()
{
memset(vis,0,sizeof(vis));
queue<node>q;
q.push(node(1,1,0,1|bmap[1][1]));
vis[1][1][1|bmap[1][1]] = 1;
while(!q.empty())
{
node fr = q.front(); q.pop();
for(int i=0;i<4;i++)
{
int nx = fr.x+dir[i][0];
int ny = fr.y+dir[i][1];
int a = fr.x*m+fr.y;
int b = nx*m+ny;
int kk = door[make_pair(a,b)];
if(nx>n||ny>m||nx<=0||ny<=0||!(fr.key&(1<<kk))||vis[nx][ny][fr.key]) continue;
if(nx==n&&ny==m)
{
printf("%d\n",fr.step+1);
return ;
}
vis[nx][ny][fr.key|bmap[nx][ny]] = 1;
q.push(node(nx,ny,fr.step+1,fr.key|bmap[nx][ny]));
}
}
printf("-1\n");
}
int main()
{
//printf("%d\n",(1<<12)*51*51);
int x1,y1,x2,y2,w;
while(scanf("%d%d%d",&n,&m,&p)!=EOF)
{
door.clear();
memset(bmap,0,sizeof(bmap));
memset(sumkey,0,sizeof(sumkey));
scanf("%d",&k);
for(int i=0;i<k;i++)
{
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&w);
w++;
door[make_pair(x1*m+y1,x2*m+y2)] = w;
door[make_pair(x2*m+y2,x1*m+y1)] = w;
}
scanf("%d",&numk);
while(numk--)
{
scanf("%d%d%d",&x1,&y1,&w);
w++;
bmap[x1][y1] |= (1<<w);
}
bfs();
}
return 0;
}