题目链接:Codeforces 329B Biridian Forest
BFS。
不难想到,若小队a距出口的最小距离小于等于主人公距出口的最小距离,小队a一定可一追到主人公,所以只要以出口为起点,做一个bfs记录下出口到各点的距离,之后统计人数即可。需要注意的一点是有些区域可能会被障碍物个离开,初始化的时候要将所有区域到出口的距离设为无穷大,不然在统计时可能会把隔了区的小队人数也统计进去。
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
const int MAX_N = 1000 + 100;
const int fx[5]={0,0,1,0,-1};
const int fy[5]={0,1,0,-1,0};
const int inf = (1 << 30);
int dis[MAX_N][MAX_N];
bool vis[MAX_N][MAX_N];
char _map[MAX_N][MAX_N];
struct Node
{
int x,y,num;
};
struct Point
{
int x,y,dis;
};
Node node[MAX_N * MAX_N];
Node st,en;//start,end
int r,c;
void BFS()
{
queue<Point> point;
Point p_en;
p_en.x = en.x;
p_en.y = en.y;
p_en.dis = 0;
point.push(p_en);
vis[p_en.x][p_en.y] = true;
while(!point.empty())
{
Point q = point.front();
point.pop();
Point _new;
for(int i = 1;i <= 4;i++)
{
_new.x = q.x + fx[i];
_new.y = q.y + fy[i];
if(_new.x <= r && _new.x > 0 && _new.y <= c && _new.y > 0 && _map[_new.x][_new.y] != 'T' && !vis[_new.x][_new.y])
{
_new.dis = q.dis + 1;
vis[_new.x][_new.y] = true;
point.push(_new);
dis[_new.x][_new.y] = _new.dis;
}
}
}
}
int main()
{
memset(vis,0,sizeof(vis));
int cnt = 0;
cin >> r >> c;
for(int i = 1;i <= r;i++)
{
for(int j = 1;j <= c;j++)
{
cin >> _map[i][j];
dis[i][j] = inf;
if(_map[i][j] == 'S')
{
st.x = i;
st.y = j;
}
else if(_map[i][j] == 'E')
{
en.x = i;
en.y = j;
}
else if(_map[i][j] >= '0' && _map[i][j] <= '9')
{
cnt++;
node[cnt].x = i;
node[cnt].y = j;
node[cnt].num = _map[i][j] - '0';
}
}
}
BFS();
int ans = 0;
for(int i = 1;i <= cnt;i++)
{
if(dis[node[i].x][node[i].y] <= dis[st.x][st.y])
ans += node[i].num;
}
cout << ans << endl;
return 0;
}