题目链接:https://codeforces.com/contest/1433/problem/G
题解
跑 (n) 遍 (dijkstra) 得到任意两点间的距离,然后枚举哪一条边权为 (0) 即可。
代码
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m, k;
cin >> n >> m >> k;
vector<vector<pair<int, int>>> G(n);
vector<tuple<int, int, int>> edges(m);
for (auto &[u, v, w] : edges) {
cin >> u >> v >> w;
--u, --v;
G[u].emplace_back(w, v);
G[v].emplace_back(w, u);
}
vector<vector<int>> dis(n, vector<int> (n));
auto dijkstra = [&](int s, vector<int> &d) {
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pque;
vector<bool> vis(n);
pque.emplace(0, s);
while (not pque.empty()) {
auto [w1, u] = pque.top();
pque.pop();
if (vis[u]) continue;
d[u] = w1;
vis[u] = true;
for (auto [w2, v] : G[u]) {
pque.emplace(w1 + w2, v);
}
}
};
for (int i = 0; i < n; i++) {
dijkstra(i, dis[i]);
}
int ans = 0;
vector<pair<int, int>> route(k);
for (auto &[a, b] : route) {
cin >> a >> b;
--a, --b;
ans += dis[a][b];
}
for (auto [u, v, w] : edges) {
int now = 0;
for (auto [a, b] : route) {
now += min({dis[a][b], dis[a][u] + dis[v][b], dis[a][v] + dis[u][b]});
}
ans = min(ans, now);
}
cout << ans << "
";
return 0;
}