链接:
https://www.nowcoder.com/acm/contest/118/A
来源:牛客网
来源:牛客网

最近,喜爱ACM的PBY同学沉迷吃鸡,无法自拔,于是又来到了熟悉的ERANGEL。经过一番搜寻,PBY同学准备动身前往安全区,但是,地图中埋伏了许多LYB,PBY的枪法很差,希望你能够帮他找到一条路线,每次只能向上、下、左、右移动,尽可能遇到较少的敌人。
输入描述:
题目包含多组测试,请处理到文件结束; 第一行是一个整数n,代表地图的大小; 接下来的n行中,每行包含n个整数a,每个数字a代表当前位置敌人的数量; 1 < n <= 100,1 <= a <= 100,-1代表当前位置,-2代表安全区。
输出描述:
对于每组测试数据,请输出从当前位置到安全区所遇到最少的敌人数量,每个输出占一行。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 10010;
int n, st, ed;
bool inq[maxn];
int a[107][107];
int d[maxn];
const int dirx[] = {0,0,1,-1};
const int diry[] = {1,-1,0,0};
vector<pair<int, int> > G[maxn];
bool inside(int i, int j)
{
return i >= 1 && j >= 1 && i <= n && j <= n;
}
struct cmp
{
bool operator () (int &t1, int &t2) const {
return d[t1] > d[t2];
}
};
void spfa()
{
d[st] = 0;
priority_queue<int, vector<int>, cmp> que;
que.push(st);
inq[st] = 1;
while(!que.empty()) {
int u = que.top(); que.pop();
inq[u] = 0;
for(int i = 0;i < G[u].size();i ++) {
int v = G[u][i].first;
int w = G[u][i].second;
if(d[v] > d[u] + w) {
d[v] = d[u] + w;
if(!inq[v]) {
que.push(v);
inq[v] = 1;
}
}
}
}
}
int main()
{
while(~scanf("%d", &n)) {
memset(d, 0x3f, sizeof(d));
for(int i = 1; i <= n; i ++) {
for(int j = 1; j <= n; j ++) {
scanf("%d", &a[i][j]);
if(a[i][j] == -1) st = (i - 1) * n + j;
if(a[i][j] == -2) ed = (i - 1) * n + j;
}
}
for(int i = 1; i <= n; i ++) {
for(int j = 1; j <= n; j ++) {
int now = (i - 1) * n + j;
G[now].clear();
for(int k = 0;k < 4;k ++) {
int di = i + dirx[k];
int dj = j + diry[k];
if(inside(di, dj)) {
int p = (di - 1) * n + dj;
if(a[di][dj] < 0) G[now].push_back(make_pair(p, 0));
else G[now].push_back(make_pair(p, a[di][dj]));
}
}
}
}
spfa();
printf("%d\n", d[ed]);
}
return 0;
}