[codevs 1911] 孤岛营救问题
生活随笔
收集整理的這篇文章主要介紹了
[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; }
咦?當時有個點沒過,有好心人幫我看看哪錯了吧……
總結
以上是生活随笔為你收集整理的[codevs 1911] 孤岛营救问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [codevs 1916] 负载平衡问题
- 下一篇: [codevs 1034] 家园