链接:
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; }