社区讨论

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 条回复,欢迎继续交流。

正在加载回复...