您的位置:首页 > 其它

hdu 4845 : 拯救大兵瑞恩 (bfs+状态压缩)

2017-08-08 16:55 471 查看
题目链接

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;

int n,m,p,s,k;
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};

bool vis[16][16][1<<11];    //vis[i][j][k]记录是否以k状态访问过(i,j)位置
int wall[16][16][16][16];    //记录墙和门的情况
int key[16][16];            //记录迷宫中钥匙的存在状态

struct node
{
int x,y;        //x,y记录坐标
int own;        //own记录钥匙的拥有情况
int dis;        //dis记录到原点的最短距离
};

bool in(int x,int y)
{
return 1<=x&&x<=n&&1<=y&&y<=m;
}

int bfs()
{
vis[1][1][key[1][1]]=1;
queue<node> q;
q.push((node){1,1,key[1][1],0});
while(!q.empty())
{
node cur=q.front();
q.pop();
int px=cur.x,py=cur.y,pdis=cur.dis;
for(int i=0;i<4;i++)
{
int own=cur.own;
int x=px+dx[i];
int y=py+dy[i];
if(!in(x,y)||wall[px][py][x][y]==0) continue;    //不在边界内或是一堵墙
int door= (wall[px][py][x][y]==-1? 0:wall[px][py][x][y]);
if(!(own&(1<<door)))    continue;    //没有钥匙
if(x==n&&y==m) return pdis+1;        //到达终点
own|=key[x][y];        //捡到该点的钥匙
if(vis[x][y][own])    continue;
vis[x][y][own]=1;
q.push((node){x,y,own,pdis+1});
}
}
return -1;
}

int main()
{
while(cin>>n>>m>>p)
{
memset(wall,-1,sizeof(wall));
memset(key,0,sizeof(key));
memset(vis,0,sizeof(vis));
cin>>k;
while(k--)
{
int x1,y1,x2,y2,g;
cin>>x1>>y1>>x2>>y2>>g;
wall[x1][y1][x2][y2]=wall[x2][y2][x1][y1]=g;
}
cin>>s;
while(s--)
{
int x,y,q;
cin>>x>>y>>q;
key[x][y]|=1<<q;
}
key[1][1]|=1;    //捡到原点的钥匙
cout<<bfs()<<endl;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: