组合题5 个小题
已作答 0 / 5
(特殊最短路)给定一个含 N 个点、M 条边的带权无向图,边权非负。起点为 S,终点为 T。对于一条 S 到 T 的路径,可以在整条路径中,至多选择一条边作为“免费边”:当第一次经过这条被选中的边时,费用视为 0;如果之后再次经过该边,则仍按其原始权重计费。点和边均允许重复经过。求从 S 到 T 的最小总费用。
以下代码求解了上述问题。试补全程序。
1#include <algorithm>2#include <iostream>3#include <queue>4#include <vector>5using namespace std;6 7const long long INF = 1e18;8 9struct Edge {10 int to;11 int weight;12};13 14struct State {15 long long dist;16 int u;17 int used_freebie; // 0 for not used, 1 for used18 bool operator>(const State &other) const {19 return dist > other.dist;20 }21};22 23int main() {24 int n, m, s, t;25 cin >> n >> m >> s >> t;26 27 vector<vector<Edge>> adj(n + 1);28 for (int i = 0; i < m; ++i) {29 int u, v, w;30 cin >> u >> v >> w;31 adj[u].push_back({v, w});32 adj[v].push_back({u, w});33 }34 35 vector<vector<long long>> d(n + 1, vector<long long>(2, INF));36 priority_queue<State, vector<State>, greater<State>> pq;37 38 d[s][0] = 0;39 pq.push({0, s, __①__});40 41 while (!pq.empty()) {42 State current = pq.top();43 pq.pop();44 45 long long dist = current.dist;46 int u = current.u;47 int used = current.used_freebie;48 49 if (dist > __②__) {50 continue;51 }52 53 for (const auto &edge : adj[u]) {54 int v = edge.to;55 int w = edge.weight;56 57 if (d[u][used] + w < __③__) {58 __③__ = d[u][used] + w;59 pq.push({__③__, v, used});60 }61 62 if (used == 0) {63 if (__④__ < d[v][1]) {64 d[v][1] = d[u][used];65 pq.push({d[v][1], v, 1});66 }67 }68 }69 }70 71 cout << __⑤__ << endl;72 return 0;73}① 处应填( )