类型:bfs + 优先队列
题目:http://acm.hdu.edu.cn/showproblem.php?pid=4198
来源:BAPC 2011
思路:扩展完当前节点后,将"路径"小的节点出队,进行扩展。
!!!S点可能在边上
// hdoj 4198 Quick out of the Harbour
// wa ac 125MS 764K
#include <iostream>
#include <sstream>
#include <string>
#include <queue>
#include <stack>
#include <map>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
#define FOR(i,a,b) for(i = (a); i < (b); ++i)
#define FORE(i,a,b) for(i = (a); i <= (b); ++i)
#define FORD(i,a,b) for(i = (a); i > (b); --i)
#define FORDE(i,a,b) for(i = (a); i >= (b); --i)
#define CLR(a,b) memset(a,b,sizeof(a))
#define PB(x) push_back(x)
const int MAXN = 510;
const int MAXM = 0;
const int hash_size = 25000002;
const int INF = 0x7f7f7f7f;
bool vis[MAXN][MAXN];
int test, h, w, d, sx, sy;
int dirx[4] = {-1, 0, 1, 0}, diry[4] = {0, 1, 0, -1};
char str[MAXN][MAXN];
struct node {
int x, y, step;
};
bool operator > (const node &a, const node &b) {
return a.step > b.step;
}
bool operator < (const node &a, const node &b) {
return a.step < b.step;
}
priority_queue<node, vector<node>, greater<node> > q;
void init() {
int i, j;
scanf("%d %d %d", &h, &w, &d);
CLR(vis, false);
while(!q.empty())
q.pop();
FORE(i, 1, h) {
scanf("%s", str[i] + 1);
FORE(j, 1, w)
if(str[i][j] == 'S')
sx = i, sy = j;
}
}
int bfs() {
int i;
node a, b;
a.x = sx, a.y = sy, a.step = 1;
q.push(a);
//!!!
if(a.x == 1 || a.x == h || a.y == 1 || a.y == w)
return a.step;
while(!q.empty()) {
a = q.top();
q.pop();
FORE(i, 0, 3) {
int tmp_x = a.x + dirx[i], tmp_y = a.y + diry[i];
if(tmp_x < 1 || tmp_x > h || tmp_y < 1 || tmp_y > w || vis[tmp_x][tmp_y] || str[tmp_x][tmp_y] == '#')
continue;
vis[tmp_x][tmp_y] = true;
b.x = tmp_x, b.y = tmp_y;
if(str[tmp_x][tmp_y] == '.')
b.step = a.step + 1;
else
b.step = a.step + 1 + d;
if(b.x == 1 || b.x == h || b.y == 1 || b.y == w)
return b.step;
q.push(b);
}
}
}
int main() {
scanf("%d", &test);
while(test--) {
init();
printf("%d\n", bfs());
}
return 0;
}