拯救大兵瑞恩 HDU - 4845 (分层)
Posted ssummerzzz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了拯救大兵瑞恩 HDU - 4845 (分层)相关的知识,希望对你有一定的参考价值。
思路:钥匙种类p = 10,我们可以拥有不同种类钥匙,通过这个我们可以把图分成2^p层,表示拥有不同种类钥匙的情况。
#include <iostream> #include <vector> #include <cstdio> #include <cstring> #include <queue> using namespace std; const int N = 17; int mv_x[] = {1, -1, 0, 0}; int mv_y[] = {0, 0, -1, 1}; int mp[N][N][N][N]; //地图相通情况 int key[N][N]; //钥匙分配情况 int step[1 << 11][N][N]; //分层图 int n, m, p, k, s; struct node{ int x, y, lev; }; bool check(int x, int y){ return x >= 1 && x <= n && y >= 1 && y <= m; } void bfs(){ queue<node > que; que.push({1, 1, 0}); step[0][1][1] = 0; while(!que.empty()){ node now = que.front(); que.pop(); int lev = now.lev; for(int p = 0; p < 4; ++p){ int dx = now.x + mv_x[p]; int dy = now.y + mv_y[p]; //越界 if(!check(dx, dy)) continue; //走过了 if(step[lev][dx][dy] != -1) continue; int info = mp[now.x][now.y][dx][dy]; //是墙 if(info == 0) continue; //需要钥匙 if(info != -1){ //没这类钥匙 if((lev | (1 << (info - 1))) != lev) continue; //有这类钥匙 step[lev][dx][dy] = step[lev][now.x][now.y] + 1; que.push({dx, dy, lev}); //下一步有钥匙 if(key[dx][dy]){ //捡起钥匙 step[lev | key[dx][dy]][dx][dy] = step[lev][dx][dy]; que.push({dx, dy, lev | key[dx][dy]}); } }else{ //不需要钥匙 step[lev][dx][dy] = step[lev][now.x][now.y] + 1; que.push({dx, dy, lev}); //下一步有钥匙 if(key[dx][dy]){ //捡起钥匙 step[lev | key[dx][dy]][dx][dy] = step[lev][dx][dy]; que.push({dx, dy, lev | key[dx][dy]}); } } } } } void solve(){ while(~scanf("%d%d%d%d", &n, &m, &p, &k)){ memset(mp, -1, sizeof(mp)); memset(key, 0, sizeof(key)); memset(step, -1, sizeof(step)); int x1, x2, y1, y2, g; for(int i = 0; i < k; ++i){ scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &g); mp[x1][y1][x2][y2] = g; mp[x2][y2][x1][y1] = g; } scanf("%d", &s); for(int i = 0; i < s; ++i){ scanf("%d%d%d", &x1, &y1, &g); key[x1][y1] |= (1 << (g - 1)); } bfs(); int ans = 1e9; for(int i = 0; i <= 1030; ++i){ if(step[i][n][m] == -1) continue; ans = min(ans, step[i][n][m]); } printf("%d ", ans == 1e9 ? -1 : ans); } } int main(){ solve(); //cout << "not error" << endl; return 0; }
以上是关于拯救大兵瑞恩 HDU - 4845 (分层)的主要内容,如果未能解决你的问题,请参考以下文章
「hdu 4845 」拯救大兵瑞恩(状态压缩bfs | 分层图思想)
拯救大兵瑞恩 HDU - 4845(状压bfs || 分层最短路)