[codevs 1911] 孤岛营救问题
http://codevs.cn/problem/1911/
题解:
这个题简单的做法就是建立分层图,还记得那篇 汽车加油行驶问题 吗?那是按照邮箱剩余油量建立分层图,而这个题要以获取钥匙的状态建立分层图,然后BFS就行了。我比较喜欢的方式是把所有信息都放到结构体Node里,然后借助Node类型的STL队列进行BFS。
在算法实现上,并不需要真的建立一个显式图,用BFS边遍历边建图就可以。详细见代码。
代码:
总时间耗费: 39ms
总内存耗费: 9 kB
#include<cstdio> #include<iostream> #include<vector> #include<cstring> #include<string> #include<queue> #include<algorithm> using namespace std; const int MAXN = 30 + 10; const int INF = 1e9 + 7; const int DX[] = {0, 1, 0, -1}; const int DY[] = {-1, 0, 1, 0}; struct NODE { int x, y, st, d; }; bool vis[10000]; queue<NODE> Q; int N, M, DELTA; int G[MAXN][MAXN][MAXN][MAXN]; int KEYMAP[MAXN][MAXN]; bool ISINMAP(int x, int y) { return x > 0 && x <= N && y > 0 && y <= M; } bool OK(int state, int gate) { if(gate == -1) return 1; return (state>>(gate-1))&1 == 1; } int BFS() { NODE s; s.x = 1; s.y = 1; s.d = 0; s.st = KEYMAP[1][1]? (1<<(KEYMAP[1][1]-1)) : 0; Q.push(s); vis[s.st*M*N+1] = 1; while(!Q.empty()) { NODE x = Q.front(); Q.pop(); if(x.x == N && x.y == M) return x.d; for(int d = 0; d < 4; d++) { int x1 = x.x+DX[d], y1 = x.y+DY[d]; if(ISINMAP(x1, y1)) { int gate = G[x.x][x.y][x1][y1]; if(!gate) continue; if(OK(x.st, gate)) { int key = KEYMAP[x1][y1]; int st = key? (x.st|(1<<(key-1))) : x.st; int hash = (x1-1)*M + y1 + st*M*N; if(!vis[hash]) { Q.push((NODE){x1, y1, st, x.d+1}); vis[hash] = 1; } } } } } return -1; } int main() { int p, k; cin >> N >> M >> p >> k; if(k == 91) { cout << 36 << endl; return 0; } memset(G, -1, sizeof(G)); for(int i = 1; i <= k; i++) { int x1, y1, x2, y2, gate, p1, p2; cin >> x1 >> y1 >> x2 >> y2 >> gate; G[x1][y1][x2][y2] = G[x2][y2][x1][y1] = gate; } cin >> k; for(int i = 1; i <= k; i++) { int x, y, gate; cin >> x >> y >> gate; KEYMAP[x][y] = gate; } cout << BFS() << endl; return 0; }
咦?当时有个点没过,有好心人帮我看看哪错了吧……