P10948 升降梯上(dijkstra)
题目链接:P10948 升降梯上 - 洛谷
题目大意:
从1层到N层,每次可扳动手柄选择移动槽 C[i](相邻槽切换1秒,初始位置在移动层数为0的槽),
电梯移动每层2秒。给定M个槽位对应的移动层数(有正负),
求1层到达N层的最短时间,若不能到达输出-1(不可达)。
,
思路:
跑 Dijkstra 时枚举 数组
计算出从当前层可以到哪些层以及到那一层所花费的时间。
用结构体存 { 点1到当前点最短时间,当前节点,对应的槽的位置 }
按时间从小到大用优先队列排序
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<stack>
#include<set>
#include<map>
#include<unordered_set>
#include<unordered_map>
#include<bitset>
#include<tuple>
#define inf 72340172838076673
#define int long long
#define endl '\n'
#define F first
#define S second
#define mst(a,x) memset(a,x,sizeof (a))
using namespace std;
typedef pair<int, int> pii;
const int N = 1008, mod = 998244353;
int n, m;
int c[N];
int dis[N];
bool st[N];
struct node {
int d, u, pos;
bool operator<(const node &b)const {
return d > b.d;
}
};
priority_queue<node>q;
void dij() {
while (q.size()) {
auto [d, u, pos] = q.top();
q.pop();
if (st[u]) continue;
st[u] = true;
for (int i = 1; i <= m; i++) {
int j = u + c[i];
if (j < 1 || j > n) continue;
int w = abs(pos - i) +2 * abs(c[i]);
if (dis[j] > d + w) {
dis[j] = d + w;
q.push({dis[j], j, i});
}
}
}
}
void solve() {
mst(dis, 1);
cin >> n >> m;
for (int i = 1; i <= m; i++) {
cin >> c[i];
if (c[i] == 0) {
q.push({dis[1] = 0, 1, i});
}
}
dij();
if (dis[n] > inf / 2) cout << -1 << endl;
else cout << dis[n] << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T = 1;
// cin >> T;
while (T--) solve();
return 0;
}

浙公网安备 33010602011771号