题目链接:http://acm.hrbust.edu.cn/vj/index.php?/vj/index.php?c=&c=contest-contest&cid=134#problem/7
很简单的广搜题。依然没有顺利的1A。没用优先队列。搞不清是不是还要回溯一下?【啊哈哈。我就是这么想的。】
// hrbust 1621 迷宫问题II // 优先队列——广搜 // 什么时候需要回溯什么时候不需要? #include <stdio.h> #include <string.h> #include <iostream> #include <queue> using namespace std; #define maxn 100000 char mp[210][210]; int dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1}; int vis[210][210]; int r, c; int step[210][210]; int stx, sty, edx, edy; bool check(int x, int y) { if (x >= 0 && x < r && y >= 0 && y < c && !vis[x][y] && mp[x][y] != '#') return true; return false; } struct Node { friend bool operator < (Node n1, Node n2) { return step[n1.x][n1.y] > step[n2.x][n2.y];//"<"为从大到小排列,">"为从小打到排列 } int x, y; }node[40100]; priority_queue<Node> qn; void bfs(int x, int y) { int head = 0, tail = 0; memset(vis, 0, sizeof(vis)); for (int i=0; i<r; ++i) { for (int j=0; j<c; ++j) { step[i][j] = maxn; } } while(!qn.empty()) { qn.pop(); } vis[x][y] = 1; step[x][y] = 0; Node temp; temp.x = x; temp.y = y; // node[tail++] = temp; qn.push(temp); //while(head < tail) { while(!qn.empty()) { //Node now = node[head++]; Node now = qn.top(); qn.pop(); for (int i=0; i<4; ++i) { temp.x = now.x + dir[i][0]; temp.y = now.y + dir[i][1]; int tstep = 0; if (check(temp.x, temp.y)) { if (mp[temp.x][temp.y] >= '1' && mp[temp.x][temp.y] <= '9') tstep = mp[temp.x][temp.y] - '0' + 1; else tstep = 1; step[temp.x][temp.y] = min(step[temp.x][temp.y], step[now.x][now.y] + tstep); vis[temp.x][temp.y] = 1; //node[tail++] = temp; qn.push(temp); if (temp.x == edx && temp.y == edy) break; } } } return; } int main() { int t; cin >> t; while(t--) { cin >> r >> c; for (int i=0; i<r; ++i) { for (int j=0; j<c; ++j) { cin >> mp[i][j]; if (mp[i][j] == 'Z') { stx = i, sty = j; } else if (mp[i][j] == 'W') { edx = i, edy = j; } } } bfs(stx, sty); int ans = step[edx][edy]; if (ans == maxn) { cout << "IMPOSSIBLE\n"; } else cout << ans << endl; } return 0; }