社区讨论
60pts,码风良好,求调!
P10726[GESP202406 八级] 空间跳跃参与者 2已保存回复 4
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @mhj99goi
- 此快照首次捕获于
- 2025/11/03 22:48 4 个月前
- 此快照最后确认于
- 2025/11/03 22:48 4 个月前
CPP
#include <bits/stdc++.h>
using namespace std;
const int N = 2010;
typedef pair<int, int> PII;
int n, s, t;
int dist[N];
bool st[N];
int h[N], e[N * 4], ne[N * 4], w[N * 4], idx;
struct Node {
int l, r, h, id;
} db[N];
// 为每个挡板分配两个节点ID:左端点编号为2*i-1,右端点编号为2*i
int left_id(int i) { return 2 * i - 1; }
int right_id(int i) { return 2 * i; }
void add(int a, int b, int c)
{
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}
// 判断点x是否在挡板i的区间内
bool inRange(int x, int i)
{
return db[i].l <= x && x <= db[i].r;
}
// 找到从点x正下方第一个能接住的挡板(高度小于当前挡板)
int findBelow(int x, int c, int e) {
int target = -1;
for (int i = 1; i <= n; i++) {
if (i == e) continue;
if (db[i].h < c && inRange(x, i)) {
if (target == -1 || db[i].h > db[target].h)
{
target = i;
}
}
}
return target;
}
void dijkstra(int start) {
memset(dist, 0x3f, sizeof dist);
memset(st, false, sizeof st);
dist[start] = 0;
priority_queue<PII, vector<PII>, greater<PII>> heap;
heap.push({0, start});
while (!heap.empty()) {
auto t = heap.top();
heap.pop();
int ver = t.second;
if (st[ver]) continue;
st[ver] = true;
for (int i = h[ver]; i != -1; i = ne[i]) {
int j = e[i];
if (dist[j] > dist[ver] + w[i]) {
dist[j] = dist[ver] + w[i];
heap.push({dist[j], j});
}
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
memset(h, -1, sizeof h);
cin >> n >> s >> t;
for (int i = 1; i <= n; i++) {
cin >> db[i].l >> db[i].r >> db[i].h;
db[i].id = i;
}
for (int i = 1; i <= n; i++)
{
int len = db[i].r - db[i].l;
add(left_id(i), right_id(i), len);
add(right_id(i), left_id(i), len);
}
for (int i = 1; i <= n; i++) {
// 从左端点掉落
int below_left = findBelow(db[i].l, db[i].h, i);
if (below_left != -1) {
int fallTime = db[i].h - db[below_left].h;
// 移动到左端点
int moveToLeft = abs(db[i].l - db[below_left].l);
add(left_id(i), left_id(below_left), fallTime + moveToLeft);
// 移动到右端点
int moveToRight = abs(db[below_left].r - db[i].l);
add(left_id(i), right_id(below_left), fallTime + moveToRight);
}
// 从右端点掉落
int below_right = findBelow(db[i].r, db[i].h, i);
if (below_right != -1) {
int fallTime = db[i].h - db[below_right].h;
// 移动到右端点
int moveToRight = abs(db[i].r - db[below_right].r);
add(right_id(i), right_id(below_right), fallTime + moveToRight);
// 移动到左端点
int moveToLeft = abs(db[i].r - db[below_right].l);
add(right_id(i), left_id(below_right), fallTime + moveToLeft);
}
}
dijkstra(left_id(s));
int target_l = left_id(t);
int target_r = right_id(t);
int ans = min(dist[target_l], dist[target_r]);
if (ans >= 0x3f3f3f3f) {
cout << -1 << "\n";
} else {
cout << ans << "\n";
}
return 0;
}
回复
共 4 条回复,欢迎继续交流。
正在加载回复...