题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4198
题目大意: 给你一张地图,”S“为起点,"#"不能走,走过一个"."需要1个单位时间, 走过一个”@“需要d+1的单位时间,求中起点走出地图的最短时间……
思路:我的第一反应是拆点……把一个“@”拆成d+1个,然后BFS但是这么写真的好麻烦啊!
可以用优先队列+BFS,先扩展路径长度比较短的点,然后不就求出最短路了么?
表示我写BFS都是手工队列……果然得好好学STL……
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
using namespace std;
const int N = 1010;
struct ty
{
int x, y, time;
friend bool operator < (ty a, ty b)
{
return a.time > b.time;
}
};
priority_queue<ty> qu;
char map[N][N];
int visit[N][N];
int sx, sy, h, w, d;
const int dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
int Bfs()
{
ty now, next;
while(!qu.empty()) qu.pop();
now.x = sx;
now.y = sy;
now.time = 1;
qu.push(now);
visit[sx][sy]=1;
while(!qu.empty())
{
now = qu.top();
qu.pop();
for(int i = 0; i < 4;i++)
{
next.x = now.x + dir[i][0];
next.y = now.y + dir[i][1];
int x = next.x, y = next.y;
if(x < 0 || x >= h || y < 0 || y >= w)
return now.time;
if(!visit[x][y] && map[x][y] != '#')
{
if(map[x][y] == '@') next.time = now.time + d + 1;
else next.time = now.time + 1;
qu.push(next);
visit[x][y] = 1;
}
}
}
return -1;
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
scanf("%d%d%d", &h, &w, &d);
for(int i = 0; i < h; i++)
{
for(int j = 0; j < w; j++)
{
scanf(" %c", &map[i][j]);
if(map[i][j] == 'S')
{
sx = i;
sy = j;
}
}
}
memset(visit, 0 ,sizeof(visit));
printf("%d\n", Bfs());
}
return 0;
}