状压搜索,队友搞定的东西,要考虑一下一个位置可能有多把钥匙就行- -。
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int dir[4][2]={-1,0,0,1,0,-1,1,0};
int map[55][55][55][55];
bool used[55][55][1<<11];
vector<int> keys[55][55];
int n,m;
class node
{
public:
int x,y;
int key;
int step;
};
bool inmap(int x,int y)
{
return x>=0&&y>=0&&x<n&&y<m;
}
int bfs()
{
memset(used,false,sizeof used);
used[0][0][0]=true;
node st;
st.x=0;
st.y=0;
st.step=0;
st.key=0;
queue<node> q;
while(!q.empty())
q.pop();
q.push(st);
while(!q.empty())
{
node cur=q.front(),next;
q.pop();
for(int i=0;i<4;i++)
{
next.x=cur.x+dir[i][0];
next.y=cur.y+dir[i][1];
if(!inmap(next.x,next.y))
continue;
next.step=cur.step+1;
next.key=cur.key;
/*
if(keys[next.x][next.y]!=0)
next.key|=1<<keys[next.x][next.y];*/
if(keys[next.x][next.y].size()!=0)
{
for(int j=0;j<keys[next.x][next.y].size();j++)
next.key|=1<<keys[next.x][next.y][j];
}
if(map[next.x][next.y][cur.x][cur.y]==0||used[next.x][next.y][next.key])
continue;
if(map[next.x][next.y][cur.x][cur.y]!=-1&&((1<<map[next.x][next.y][cur.x][cur.y])&next.key)==0)
continue;
if(next.x==n-1&&next.y==m-1)
return next.step;
used[next.x][next.y][next.key]=true;
q.push(next);
}
}
return -1;
}
int main()
{
int k;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(map,-1,sizeof map);
scanf("%*d");
scanf("%d",&k);
while(k--)
{
int a[6];
for(int i=0;i<5;i++)
scanf("%d",&a[i]);
map[a[0]-1][a[1]-1][a[2]-1][a[3]-1]=a[4];
map[a[2]-1][a[3]-1][a[0]-1][a[1]-1]=a[4];
}
scanf("%d",&k);
for(int i=0;i<50;i++)
for(int j=0;j<50;j++)
keys[i][j].clear();
while(k--)
{
int a[3];
for(int i=0;i<3;i++)
scanf("%d",&a[i]);
keys[a[0]-1][a[1]-1].push_back(a[2]);
}
printf("%d\n",bfs());
}
return 0;
}