Alatúlië,Heldo!

CSP-S2026 T2

为什么考场就是没想到啊,为什么(bushi)

仔细一看不难,考场上想到了地铁线建图,但没时间打Floyd了(大悲)

看一下题目,就只需要记录一下每个地铁站有几条路线经过,如果大于等于2就可以作为一条边建图,边权就是两条铁路线到站厅的时间和,最后Floyd一下就完美结束了

#include <bits/stdc++.h>
using namespace std;

#define int long long

const int N = 505;
const long long INF = (1LL << 60);

int n, m, d, q, c;
int w[500005];
int dis[N][N];

// 每个站有哪些线路经过
// first:线路编号
// second:站厅到站台时间
vector<pair<int, int>> station[500005];

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> c >> n >> m >> d >> q;

    for (int i = 1; i <= m; i++) {
        cin >> w[i];
    }

    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            if (i == j) dis[i][j] = 0;
            else dis[i][j] = INF;
        }
    }

    // 输入每条地铁线路
    for (int i = 1; i <= n; i++) {
        int k;
        cin >> k;

        for (int j = 1; j <= k; j++) {
            int a, t;
            cin >> a >> t;
            station[a].push_back({i, t});
        }
    }

    // 建图:枚举每个站的换乘线路
    for (int v = 1; v <= m; v++) {
        int sz = station[v].size();

        for (int i = 0; i < sz; i++) {
            for (int j = i + 1; j < sz; j++) {
                int x = station[v][i].first;
                int y = station[v][j].first;

                int cost = station[v][i].second
                         + station[v][j].second;

                dis[x][y] = min(dis[x][y], cost);
                dis[y][x] = min(dis[y][x], cost);
            }
        }
    }

    // Floyd:线路之间的最短换乘时间
    for (int k = 1; k <= n; k++) {
        for (int i = 1; i <= n; i++) {
            if (dis[i][k] == INF) continue;

            for (int j = 1; j <= n; j++) {
                if (dis[k][j] == INF) continue;

                dis[i][j] = min(
                    dis[i][j],
                    dis[i][k] + dis[k][j]
                );
            }
        }
    }

    // 回答询问
    while (q--) {
        int x, y;
        cin >> x >> y;

        int ans = INF;

        for (auto a : station[x]) {
            for (auto b : station[y]) {
                int i = a.first;
                int j = b.first;

                if (dis[i][j] == INF) continue;

                int cost = w[x] + a.second
                         + dis[i][j]
                         + b.second + w[y];

                ans = min(ans, cost);
            }
        }

        cout << ans << '\n';
    }

    return 0;
}

完美结束

 

posted @ 2026-11-06 06:37  UKE__3ms  阅读(5)  评论(0)    收藏  举报