Official

D - 荷物の配送 / Package Delivery Editorial by MtSaka Editorial for printing


\(M\) 頂点 \(K\) 辺の辺重み付きグラフにおいて、二点間最短経路クエリを \(N\) 個処理する問題です。

グラフの最短経路を求めるアルゴリズムにはダイクストラ法やベルマン・フォード法、ワーシャル・フロイド法などがあります。

この問題では、ワーシャル・フロイド法 (wikipedia)が有効です。ワーシャル・フロイド法は頂点数を \(V\) としたとき時間計算量 \(\mathrm{O}(V^3)\) で全点対最短経路を求めることができます。頂点数 \(M\)はが \(200\) 以下なので、十分高速にワーシャル・フロイド法が計算できます。

\(N\) 個のクエリはそれぞれ時間計算量 \(\mathrm{O}(1)\) で処理することができるので、全体で時間計算量 \(\mathrm{O}(M^3+N)\) で解くことができます。

実装例(C++)

#include <bits/stdc++.h>
using namespace std;
int main() {
    int n, m, k;
    cin >> n >> m >> k;
    vector<vector<long long>> dist(m, vector<long long>(m, 1e18));
    for (int i = 0; i < k; ++i) {
        int u, v, w;
        cin >> u >> v >> w;
        u--, v--;
        dist[u][v] = dist[v][u] = w;
    }
    for (int i = 0; i < m; ++i)
        for (int j = 0; j < m; ++j)
            for (int k = 0; k < m; ++k) dist[j][k] = min(dist[j][k], dist[j][i] + dist[i][k]);
    long long ans = 0;
    for (int i = 0; i < n; ++i) {
        int s, t;
        cin >> s >> t;
        s--, t--;
        ans += dist[s][t];
    }
    cout << ans << endl;
}

posted:
last update: