您的位置:首页 > 其它

NYOJ 284 坦克大战 bfs + 优先队列

2014-11-23 20:52 253 查看
这类带权的边的图,直接广搜不行,要加上优先队列,这样得到的结果才是最优的,这样每次先找权值最小的,代码如下

#include <stdio.h>
#include <iostream>
#include <queue>
#include <string.h>
using namespace std;
typedef struct Node{
int x, y;
int step;
friend bool operator < (const Node &a, const Node &b)
{
return a.step > b.step;
}
}Node;
const int MAX = 300 + 5;
int N, M;
int Map[MAX][MAX];
int next[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
Node s, e;
bool match(Node node)//判断是否到达终点
{
if (node.x == e.x && node.y == e.y)
return true;
return false;
}
bool check(Node node)//判断这个点是否能走
{
if (node.x < 0 || node.y < 0 || node.x >= N || node.y >= M || Map[node.x][node.y] == 0)
return false;
return true;
}
int bfs()
{
priority_queue<Node> q;//优先队列
q.push(s);
Node p1, p2;
while (!q.empty())
{
p1 = q.top();
q.pop();
for (int i = 0; i < 4; i++)
{
p2.x = p1.x + next[i][0];
p2.y = p1.y + next[i][1];
p2.step = p1.step + Map[p2.x][p2.y];
if (match(p2))
{
return p2.step;
}
if (check(p2))
{
Map[p2.x][p2.y] = 0;
Node v = p2;
q.push(v);
}
}
}
return -1;
}
int main()
{
char ch;
while (~scanf("%d%d", &N, &M) && N + M)
{
for (int i = 0; i < N; i++)
{
for (int j = 0; j < M; j++)
{
cin >> ch;
if (ch == 'Y')//起点
{
s.x = i;
s.y = j;
s.step = 0;
Map[i][j] = 0;
}
else if (ch == 'T')//终点
{
e.x = i;
e.y = j;
e.step = 0;
Map[i][j] = 1;
}
else if (ch == 'B')//普通砖块,权值为2
{
Map[i][j] = 2;
}
else if (ch == 'E')//空地,权值为1
{
Map[i][j] = 1;
}
else
{
Map[i][j] = 0;//为0的时候表示此点不可走
}
}
}
printf("%d\n", bfs());
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: