组合题

(特殊最短路)给定一个含 NN 个点、MM 条边的带权无向图,边权非负。起点为 SS,终点为 TT。对于一条 SS 到 TT 的路径,可以在整条路径中,至多选择一条边作为“免费边”:当第一次经过这条被选中的边时,费用视为 0;如果之后再次经过该边,则仍按其原始权重计费。点和边均允许重复经过。求从 SS 到 TT 的最小总费用。

以下代码求解了上述问题。试补全程序。

#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; // 0 for not used, 1 for used    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] = d[u][used];                    pq.push({d[v][1], v, 1});                }            }        }    }     cout << __⑤__ << endl;    return 0;}
第34题单选题原卷 3 分

① 处应填( )

填写答案
第35题单选题原卷 3 分

② 处应填( )

填写答案
第36题单选题原卷 3 分

③ 处应填( )

填写答案
第37题单选题原卷 3 分

④ 处应填( )

填写答案
第38题单选题原卷 3 分

⑤ 处应填( )

填写答案