万卷网 > 题目详情
题型:组合题

特殊最短路

题目背景

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

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

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(    ①   ); // ①处待完善(注:原文①处对应初始化相关)
    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;
            // 情况1:不使用免费边
            if (d[v][used] >    ③    + w) { // ③处待完善
                d[v][used] = d[u][used] + w;
                pq.push({d[v][used], v, used});
            }
            // 情况2:使用免费边(仅当未使用过)
            if (used == 0 && d[v][1] >    ④     + 0) { // ④处待完善
                d[v][1] = d[u][0] + 0;
                pq.push({d[v][1], v, 1});
            }
        }
    }
    cout <<     ⑤    << endl; // ⑤处待完善
    return 0;
}
(1).

②处应填?  

A.

d[u][!used]

B.

d[u][used]

C.

d[t][used]

D.

INF

(2).

⑤处应填?

A.

d[t][1]

B.

d[t][0]

C.

min(d[t][0], d[t][1])

D.

d[t][0] + d[t][1]

(3).

①处应填?  

A.

B.

1

C.

-1

D.

false

(4).

③处应填?

A.

d[v][1]

B.

d[v][used]

C.

d[u][used]

D.

d[v][0]

(5).

④处应填?

A.

d[v][0]

B.

d[v][1]

C.

d[u][0]

D.

d[u][1]

更新时间:2025-10-16 09:24:49 |
【知识点】 CCF非专业级别软件能力认证CSP-S/提高级

相似题推荐

简答题

T4员工招聘

2026-04-17
简答题

T1社团招新

2026-04-17
简答题

T2道路修复

2026-04-17
简答题

T3谐音替换

2026-04-16
单选题

对一个大小为16(下标0-15)的数组构建满线段树,查询区间[3,11]时,最少需要访问多少个树结点(包括路径上的父结点和完全包含在查询区间内的结点)?

A.

7

B.

8

C.

9

D.

10

2025-10-17
公众号
客服 反馈
顶部