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