hdu 5091 Maze (bfs+状态压缩)
2014-12-06 20:43
369 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5094
题意:给定一张格子图,(1,1)为起点,(n,m)为终点,每个节点和它相邻的节点会存在墙和门,其中门有好多种,当到达这个位置的时候如果你没有这个门的钥匙的话,就不能穿过这个门,每种门的钥匙分散在图上的个个地方,问从起点到终点的最短距离。
思路:大bfs,加一维来表示到达每个地方时所获钥匙的状态,dp[x][y][k]表示到达图上x,y这个地方时所获钥匙状态为k时的最短路径,对于每个位置就向四个方向搜救行了,状态转移时要考虑墙和门。
像这样的题目思路大家都知道,就是写起来的时候要注意,每个地方都要思考用尽量好的姿势来做,具体细节看代码~
code:
题意:给定一张格子图,(1,1)为起点,(n,m)为终点,每个节点和它相邻的节点会存在墙和门,其中门有好多种,当到达这个位置的时候如果你没有这个门的钥匙的话,就不能穿过这个门,每种门的钥匙分散在图上的个个地方,问从起点到终点的最短距离。
思路:大bfs,加一维来表示到达每个地方时所获钥匙的状态,dp[x][y][k]表示到达图上x,y这个地方时所获钥匙状态为k时的最短路径,对于每个位置就向四个方向搜救行了,状态转移时要考虑墙和门。
像这样的题目思路大家都知道,就是写起来的时候要注意,每个地方都要思考用尽量好的姿势来做,具体细节看代码~
code:
#include <cstdio> #include <cstdlib> #include <iostream> #include <algorithm> #include <cstring> #include <queue> #define INF 1000000007 using namespace std; const int maxn=55; const int maxe=100000; int dp[maxn][maxn][1<<11]; //door 为门数组 -1 表示没有障碍物 0 表示存在墙 1~。。 表示存在哪种门 数组的最后一维用来表示方向 //key为钥匙数组 用二进制来表示每个位置都放了那几种钥匙 int door[maxn][maxn][4]; int key[maxn][maxn]; int n,m,q; int dx[4]={-1,1,0,0}; int dy[4]={0,0,-1,1}; struct node { int x,y,st; node(){}; node(int x,int y,int st): x(x),y(y),st(st){} }; queue<node> qq; void bfs(int x,int y) { memset(dp,-1,sizeof(dp)); qq.push(node(x,y,0)); dp[x][y][0]=0; while(qq.size()){ node v=qq.front(); qq.pop(); for(int i=0;i<4;i++){ int mx=v.x+dx[i],my=v.y+dy[i],ms=v.st; if(mx<1||mx>n||my<1||my>m) continue; if(door[v.x][v.y][i]==0) continue; if(door[v.x][v.y][i]==-1||(1<<(door[v.x][v.y][i]-1)&v.st)){ ms|=key[mx][my]; if(dp[mx][my][ms]==-1||dp[mx][my][ms]>dp[v.x][v.y][v.st]+1){ dp[mx][my][ms]=dp[v.x][v.y][v.st]+1; qq.push(node(mx,my,ms)); } } } } int res=INF; for(int i=0;i<(1<<q);i++) if(dp [m][i]!=-1) res=min(res,dp [m][i]); if(res==INF) printf("-1\n"); else printf("%d\n",res); } int main() { int kk; int x1,x2,y1,y2,g; while(scanf("%d%d%d",&n,&m,&q)!=EOF){ memset(door,-1,sizeof(door)); memset(key,0,sizeof(key)); scanf("%d",&kk); while(kk--){ scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&g); int i; for(i=0;i<4;i++){ int mx=x1+dx[i],my=y1+dy[i]; if(mx==x2&&my==y2) break; } //注意建立双向门 door[x1][y1][i]=g; door[x2][y2][i^1]=g; } scanf("%d",&kk); while(kk--){ scanf("%d%d%d",&x1,&y1,&g); key[x1][y1]|=1<<(g-1); } bfs(1,1); } return 0; }
相关文章推荐
- hdu 5094 Maze (bfs+状态压缩)
- BFS+状态压缩 hdu-1885-Key Task
- hdu 1429 胜利大逃亡(续) (bfs+状态压缩)
- hdu 1429 (bfs+状态压缩)
- hdu~1429(bfs+状态压缩)
- HDU 4568 Hunter BFS+状态压缩(才13个点)
- BFS+状态压缩 hdu-1885-Key Task
- HDU_4856_Tunnels(BFS+状态压缩)
- hdu 5025 Saving Tang Monk (bfs+状态压缩)
- hdu 4856 Tunnels(bfs+状态压缩)
- hdu 5094 Maze 状态压缩dp+广搜
- BFS+状态压缩 hdu-1429 胜利大逃亡(续)
- HDU 3681 Prison Break(BFS+二分+状态压缩DP)
- hdu 1429 胜利大逃亡(续) bfs+状态压缩
- HDU-#5025 Saving Tang Monk(BFS+状态压缩)
- poj1482 & hdu1818 It's not a Bug, It's a Feature!(bfs+状态压缩)
- hdu 1429 BFS+状态压缩
- hdu 2209 翻纸牌游戏(BFS+状态压缩)
- hdu 1429(bfs+状态压缩)
- HDU-#4771 Stealing Harry Potter's Precious(bfs+状态压缩)