林老师 · 客观题题库 · 第 31 章 最短路 · 知识细节练习

第 31 章 最短路 · 知识细节练习

100 题 · 每题对应一个知识细节 · 全部原创
真题
复刻
试卷编号ORIG-第31章最短路-知识细节练习
题目总数100 题 · 100 分
试卷类型客观题
考生须知:
① 本卷共 16 大部分,合计 100 题 · 100 分,全部为客观题;
② 试卷右上角设有 「提交答卷」「重置考试」 按钮,提交后系统自动判分并显示答题正确情况,请确认全部作答后再行提交;
③ 试卷不显示答案,提交后方可查看每题作答与正确答案的对照;
④ 答卷进度会保留在本地缓存中,刷新或再次打开仍可继续作答;
⑤ 本卷仅供学生练习使用;请勿用于其他用途;题面有问题请联系:i64coder@163.com。

判 分 报 告

0 / 100 分
0
答 对 · 得 0
0
答 错 · 失 0
当前筛选下没有题目

最短路问题基础

6 QUESTIONS · 2 POINTS EACH
第 1 题 A1 未作答

最短路的定义是?

(1 分)
第 2 题 A2 未作答

判断题:图有两种基本表示——邻接矩阵(O(n2)O(n^2) 空间、查边 O(1)O(1))与邻接表(O(n+m)O(n+m) 空间、遍历出边快)——稠密图用矩阵、稀疏图用表。

(1 分)
第 3 题 A3 未作答

单源最短路与多源最短路的区别是?

(1 分)
第 4 题 A4 未作答

判断题:Dijkstra 要求边权非负;Bellman-Ford/Floyd 可处理负权(但要求无负环)。

(1 分)
第 5 题 A5 未作答

松弛(relaxation)操作是?

(1 分)
第 6 题 A6 未作答

判断题:最短路算法总表——Dijkstra(非负单源)、Bellman-Ford(负权单源 + 判负环)、SPFA(BF 队列优化)、Floyd(多源)。

(1 分)

Dijkstra

7 QUESTIONS · 2 POINTS EACH
第 7 题 B1 未作答

Dijkstra 的核心思想是?

(1 分)
第 8 题 B2 未作答

Dijkstra 的步骤是?

(1 分)
第 9 题 B3 未作答

判断题:Dijkstra 要求所有边权非负——负权边会破坏"已确定点的 dist 不再变"的性质。

(1 分)
第 10 题 B4 未作答

朴素 Dijkstra 与堆优化 Dijkstra 的复杂度分别是?

(1 分)
第 11 题 B5 未作答

判断题:Dijkstra 中已确定(出队)的点,之后还有可能被松弛更新出更短的 dist。

(1 分)
第 12 题 B6 未作答

判断题:Dijkstra 正确性直觉——当前 dist 最小的未确定点,任何绕路都不可能比它更短(边权非负),故可确定。

(1 分)
第 13 题 B7 未作答

判断题:所有边权为 1 时,Dijkstra 退化为 BFS——dist 就是层数。

(1 分)

Bellman-Ford 与 SPFA

7 QUESTIONS · 2 POINTS EACH
第 14 题 C1 未作答

Bellman-Ford 的核心思想是?

(1 分)
第 15 题 C2 未作答

判断题:Bellman-Ford 能处理负权边(无负环时正确)。

(1 分)
第 16 题 C3 未作答

Bellman-Ford 判负环的方法是?

(1 分)
第 17 题 C4 未作答

SPFA 是 Bellman-Ford 的什么优化?

(1 分)
第 18 题 C5 未作答

SPFA 的复杂度是?

(1 分)
第 19 题 C6 未作答

判断题:SPFA 在任何数据下都不会超时——正权图上可以完全放心使用。

(1 分)
第 20 题 C7 未作答

判断题:Dijkstra 快但要求非负;BF/SPFA 支持负权但可能被卡——按边权性质选。

(1 分)

Floyd

7 QUESTIONS · 2 POINTS EACH
第 21 题 D1 未作答

Floyd 的核心思想是?

(1 分)
第 22 题 D2 未作答

Floyd 的三重循环顺序是?

(1 分)
第 23 题 D3 未作答

Floyd 的复杂度是?

(1 分)
第 24 题 D4 未作答

判断题:Floyd 一次求出所有点对的最短路——适合 nn 小(如 n500n \le 500)的稠密图。

(1 分)
第 25 题 D5 未作答

判断题:Floyd 不能处理任何负权边——只要边权为负就必须改用 Bellman-Ford。

(1 分)
第 26 题 D6 未作答

Floyd 判负环的方法是?

(1 分)
第 27 题 D7 未作答

判断题:Floyd 可求传递闭包——把 min/+ 换成 or/and,d[i][j]d[i][j] 表示 i 能否到达 j。

(1 分)

次短路与变体

6 QUESTIONS · 2 POINTS EACH
第 28 题 E1 未作答

次短路的定义是?

(1 分)
第 29 题 E2 未作答

次短路的求法是?

(1 分)
第 30 题 E3 未作答

分层图思想是?

(1 分)
第 31 题 E4 未作答

判断题:最短路变体——路径计数、字典序最小路径、经过指定点——都在 Dijkstra 上加额外状态。

(1 分)
第 32 题 E5 未作答

判断题:特殊最短路(如 2025 真题"至多免费一条边")= 分层图——免费次数作为层维度。

(1 分)
第 33 题 E6 未作答

判断题:次短路与分层图是 S 组完善程序的高频变体——核心都是"扩展状态"。

(1 分)

最短路应用

6 QUESTIONS · 2 POINTS EACH
第 34 题 F1 未作答

判断题:实际问题(换乘最少/费用最低/传递消息)建模成最短路——点是状态、边是转移、权是代价。

(1 分)
第 35 题 F2 未作答

判断题:路径还原用 pre[v] = u 记录前驱,最后从终点倒推——Dijkstra/BF/SPFA 皆可。

(1 分)
第 36 题 F3 未作答

判断题:最短路计数——松弛更新时继承计数、相等时累加计数。

(1 分)
第 37 题 F4 未作答

判断题:差分约束系统(xixjcx_i - x_j \le c 类不等式)可转最短路求解——建边求最短路。

(1 分)
第 38 题 F5 未作答

判断题:Dijkstra 本质是"图上 DP"(DAG 上即拓扑序 DP)——状态是点、转移是边。

(1 分)
第 39 题 F6 未作答

判断题:最短路是图论应用最广的算法——建模能力比算法本身更重要。

(1 分)

算法选择

6 QUESTIONS · 2 POINTS EACH
第 40 题 G1 未作答

四算法总表是?

(1 分)
第 41 题 G2 未作答

n500n \le 500 的稠密图求所有点对最短路,选?

(1 分)
第 42 题 G3 未作答

判断题:堆优化 Dijkstra 在任何图上都严格优于朴素 Dijkstra。

(1 分)
第 43 题 G4 未作答

判断题:有负权边选 BF/SPFA/Floyd;有负环则最短路无意义(可无限绕圈变短)。

(1 分)
第 44 题 G5 未作答

需要"判负环 + 单源最短路",选?

(1 分)
第 45 题 G6 未作答

判断题:选择流程——先看边权(负?)、再看单源还是多源、最后看 n,mn, m 规模。

(1 分)

易错综合

5 QUESTIONS · 2 POINTS EACH
第 46 题 H1 未作答

判断题:负权图用 Dijkstra 会得到错误答案——"已确定"性质被破坏。

(1 分)
第 47 题 H2 未作答

判断题:Floyd 的 k 必须在最外层——k 在内层则 DP 含义错乱、结果可能错。

(1 分)
第 48 题 H3 未作答

判断题:SPFA 判负环 = 记录入队次数,某点入队 > n 次则有负环——忘判会死循环。

(1 分)
第 49 题 H4 未作答

判断题:dist 初始化——起点 0、其余 INF;若 INF 取太小会被误当路径长。

(1 分)
第 50 题 H5 未作答

判断题:以下结论全部正确——"Dijkstra 要求非负权;Floyd k 层在最外;SPFA 入队次数判负环;次短路维护两个 dist;分层图扩状态"。

(1 分)

Dijkstra 代码

6 QUESTIONS · 2 POINTS EACH
第 51 题 I1 未作答

01#include <bits/stdc++.h>
02using namespace std;
03const int INF = 0x3f3f3f3f;
04int main() {
05    int n = 4;
06    int w[5][5];
07    memset(w, 0x3f, sizeof w);
08    w[1][2] = 2; w[1][3] = 5; w[2][3] = 1; w[2][4] = 6; w[3][4] = 2;
09    int dist[5], vis[5] = {0};
10    for (int i = 1; i <= n; i++) dist[i] = INF;
11    dist[1] = 0;
12    for (int it = 0; it < n; it++) {
13        int u = -1;
14        for (int i = 1; i <= n; i++)
15            if (!vis[i] && (u == -1 || dist[i] < dist[u])) u = i;
16        vis[u] = 1;
17        for (int v = 1; v <= n; v++)
18            if (w[u][v] != INF && dist[v] > dist[u] + w[u][v])
19                dist[v] = dist[u] + w[u][v];
20    }
21    for (int i = 1; i <= n; i++) cout << dist[i] << " ";
22    return 0;
23}

单选题:程序输出是?(从 1 号点出发的最短路距离)

(1 分)
第 52 题 I2 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    int n = 4;
05    vector<pair<int,int>> g[5];
06    g[1].push_back({2, 2}); g[1].push_back({3, 5});
07    g[2].push_back({3, 1}); g[2].push_back({4, 6});
08    g[3].push_back({4, 2});
09    int dist[5], vis[5] = {0};
10    memset(dist, 0x3f, sizeof dist);
11    dist[1] = 0;
12    priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> q;
13    q.push({0, 1});
14    while (!q.empty()) {
15        auto [d, u] = q.top(); q.pop();
16        if (vis[u]) continue;
17        vis[u] = 1;
18        cout << u << " ";
19        for (auto [v, w] : g[u])
20            if (dist[v] > d + w) {
21                dist[v] = d + w;
22                q.push({dist[v], v});
23            }
24    }
25    return 0;
26}

单选题:程序输出是?(点被确定的最短距离顺序)

(1 分)
第 53 题 I3 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    int n = 4, s = 2;
05    vector<pair<int,int>> g[5];
06    g[1].push_back({2, 2}); g[1].push_back({3, 5});
07    g[2].push_back({3, 1}); g[2].push_back({4, 6});
08    g[3].push_back({4, 2});
09    int dist[5], vis[5] = {0};
10    memset(dist, 0x3f, sizeof dist);
11    dist[s] = 0;
12    priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> q;
13    q.push({0, s});
14    while (!q.empty()) {
15        auto [d, u] = q.top(); q.pop();
16        if (vis[u]) continue;
17        vis[u] = 1;
18        for (auto [v, w] : g[u])
19            if (dist[v] > d + w) {
20                dist[v] = d + w;
21                q.push({dist[v], v});
22            }
23    }
24    for (int i = 1; i <= n; i++) cout << dist[i] << " ";
25    return 0;
26}

单选题:程序输出是?(图是有向图,从 2 号点出发)

(1 分)
第 54 题 I4 未作答

01#include <bits/stdc++.h>
02using namespace std;
03const int INF = 0x3f3f3f3f;
04int main() {
05    int n = 4;
06    int w[5][5];
07    memset(w, 0x3f, sizeof w);
08    w[1][2] = 2; w[1][3] = 5; w[2][3] = 1; w[2][4] = 6; w[3][4] = 2;
09    int dist[5], vis[5] = {0};
10    for (int i = 1; i <= n; i++) dist[i] = INF;
11    dist[1] = 0;
12    for (int it = 0; it < n; it++) {
13        int u = -1;
14        for (int i = 1; i <= n; i++)
15            if (!vis[i] && (u == -1 || dist[i] < dist[u])) u = i;
16        vis[u] = 1;
17        for (int v = 1; v <= n; v++)
18            if (w[u][v] != INF && dist[v] > dist[u] + w[u][v])
19                dist[v] = dist[u] + w[u][v];
20        if (u == 2) {                    // 刚确定 2 号点时输出
21            for (int i = 1; i <= n; i++) cout << dist[i] << " ";
22        }
23    }
24    return 0;
25}

单选题:程序输出是?(刚确定 2 号点时的 dist 数组)

(1 分)
第 55 题 I5 未作答

01while (!q.empty()) {
02    auto [d, u] = q.top(); q.pop();
03    if (vis[u]) continue;
04    vis[u] = 1;
05    for (auto [v, w] : g[u]) {
06        if (dist[v] > d + w) {
07            dist[v] = ______;       // 更新为更短距离
08            q.push({dist[v], v});
09        }
10    }
11}

单选题:横线处应填入?

(1 分)
第 56 题 I6 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    int n = 4;
05    vector<pair<int,int>> g[5];
06    g[1].push_back({2, 2}); g[1].push_back({3, 5});
07    g[2].push_back({3, 1}); g[2].push_back({4, 6});
08    g[3].push_back({4, 3});          // 注意:3->4 的边权是 3
09    int dist[5], vis[5] = {0};
10    memset(dist, 0x3f, sizeof dist);
11    dist[1] = 0;
12    priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> q;
13    q.push({0, 1});
14    while (!q.empty()) {
15        auto [d, u] = q.top(); q.pop();
16        if (vis[u]) continue;
17        vis[u] = 1;
18        for (auto [v, w] : g[u])
19            if (dist[v] > d + w) {
20                dist[v] = d + w;
21                q.push({dist[v], v});
22            }
23    }
24    cout << dist[4];
25    return 0;
26}

单选题:程序输出是?

(1 分)

Bellman-Ford 与 SPFA 代码

6 QUESTIONS · 2 POINTS EACH
第 57 题 J1 未作答

01#include <bits/stdc++.h>
02using namespace std;
03struct Edge { int u, v, w; };
04int main() {
05    int n = 3;
06    vector<Edge> e = {{1,2,2}, {1,3,3}, {2,3,-1}};
07    int dist[4];
08    memset(dist, 0x3f, sizeof dist);
09    dist[1] = 0;
10    for (int r = 1; r <= n - 1; r++)          // 松弛 n-1 轮
11        for (auto [u, v, w] : e)
12            if (dist[v] > dist[u] + w)
13                dist[v] = dist[u] + w;
14    for (int i = 1; i <= n; i++) cout << dist[i] << " ";
15    return 0;
16}

单选题:程序输出是?(含负权边的最短路)

(1 分)
第 58 题 J2 未作答

01#include <bits/stdc++.h>
02using namespace std;
03struct Edge { int u, v, w; };
04int main() {
05    int n = 3;
06    vector<Edge> e = {{2,3,-1}, {1,2,2}, {1,3,3}};   // 注意边的顺序
07    int dist[4];
08    memset(dist, 0x3f, sizeof dist);
09    dist[1] = 0;
10    for (int r = 1; r <= n - 1; r++) {
11        for (auto [u, v, w] : e)
12            if (dist[v] > dist[u] + w)
13                dist[v] = dist[u] + w;
14        cout << dist[3] << " ";          // 每轮结束输出 dist[3]
15    }
16    return 0;
17}

单选题:程序输出是?

(1 分)
第 59 题 J3 未作答

01#include <bits/stdc++.h>
02using namespace std;
03struct Edge { int u, v, w; };
04int main() {
05    int n = 3;
06    vector<Edge> e = {{1,2,1}, {2,3,-1}, {3,1,-1}};  // 环权值和 -1
07    int dist[4];
08    memset(dist, 0x3f, sizeof dist);
09    dist[1] = 0;
10    bool neg = false;
11    for (int r = 1; r <= n; r++) {
12        bool upd = false;
13        for (auto [u, v, w] : e)
14            if (dist[v] > dist[u] + w) {
15                dist[v] = dist[u] + w;
16                upd = true;
17            }
18        if (r == n && upd) neg = true;   // 第 n 轮仍有松弛
19    }
20    cout << (neg ? "YES" : "NO");
21    return 0;
22}

单选题:程序输出是?

(1 分)
第 60 题 J4 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    int n = 3;
05    vector<pair<int,int>> g[4];
06    g[1].push_back({2, 2}); g[1].push_back({3, 3});
07    g[2].push_back({3, -1});
08    int dist[4], inq[4] = {0};
09    memset(dist, 0x3f, sizeof dist);
10    dist[1] = 0;
11    queue<int> q;
12    q.push(1); inq[1] = 1;
13    while (!q.empty()) {
14        int u = q.front(); q.pop();
15        inq[u] = 0;
16        for (auto [v, w] : g[u])
17            if (dist[v] > dist[u] + w) {
18                dist[v] = dist[u] + w;
19                if (!inq[v]) { q.push(v); inq[v] = 1; }
20            }
21    }
22    for (int i = 1; i <= n; i++) cout << dist[i] << " ";
23    return 0;
24}

单选题:程序输出是?

(1 分)
第 61 题 J5 未作答

01if (!inq[v]) {
02    q.push(v);
03    ______;          // 标记 v 已入队
04}

单选题:横线处应填入?

(1 分)
第 62 题 J6 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    int n = 3;
05    vector<pair<int,int>> g[4];
06    g[1].push_back({2, 1});
07    g[2].push_back({3, -1});
08    g[3].push_back({1, -1});
09    int dist[4], cnt[4] = {0}, inq[4] = {0};
10    memset(dist, 0x3f, sizeof dist);
11    dist[1] = 0;
12    queue<int> q;
13    q.push(1); inq[1] = 1;
14    while (!q.empty()) {
15        int u = q.front(); q.pop();
16        inq[u] = 0;
17        for (auto [v, w] : g[u])
18            if (dist[v] > dist[u] + w) {
19                dist[v] = dist[u] + w;
20                cnt[v] = cnt[u] + 1;
21                if (cnt[v] > n) { cout << "YES"; return 0; }
22                if (!inq[v]) { q.push(v); inq[v] = 1; }
23            }
24    }
25    cout << "NO";
26    return 0;
27}

单选题:程序输出是?

(1 分)
拾壹

Floyd 代码

7 QUESTIONS · 2 POINTS EACH
第 63 题 K1 未作答

01#include <bits/stdc++.h>
02using namespace std;
03const int INF = 0x3f3f3f3f;
04int main() {
05    int n = 4;
06    int d[5][5];
07    memset(d, 0x3f, sizeof d);
08    for (int i = 1; i <= n; i++) d[i][i] = 0;
09    d[1][2] = 2; d[1][3] = 5; d[2][3] = 1; d[2][4] = 6; d[3][4] = 2;
10    for (int k = 1; k <= n; k++)
11        for (int i = 1; i <= n; i++)
12            for (int j = 1; j <= n; j++)
13                d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
14    cout << d[1][4] << " " << d[2][4];
15    return 0;
16}

单选题:程序输出是?

(1 分)
第 64 题 K2 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    int n = 4;
05    int d[5][5];
06    memset(d, 0x3f, sizeof d);
07    for (int i = 1; i <= n; i++) d[i][i] = 0;
08    d[1][2] = 2; d[1][3] = 5; d[2][3] = 1; d[2][4] = 6; d[3][4] = 2;
09    for (int k = 1; k <= n; k++) {
10        for (int i = 1; i <= n; i++)
11            for (int j = 1; j <= n; j++)
12                d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
13        cout << d[1][4] << " ";       // 每层 k 结束输出 d[1][4]
14    }
15    return 0;
16}

单选题:程序输出是?

(1 分)
第 65 题 K3 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    int n = 4;
05    bool r[5][5] = {};
06    r[1][2] = r[1][3] = r[2][3] = r[2][4] = r[3][4] = true;
07    for (int i = 1; i <= n; i++) r[i][i] = true;
08    for (int k = 1; k <= n; k++)
09        for (int i = 1; i <= n; i++)
10            for (int j = 1; j <= n; j++)
11                r[i][j] = r[i][j] || (r[i][k] && r[k][j]);
12    for (int j = 1; j <= n; j++) cout << r[1][j] << " ";
13    cout << endl;
14    for (int j = 1; j <= n; j++) cout << r[4][j] << " ";
15    return 0;
16}

单选题:程序输出是?(第一行 = 1 号点能否到达各点,第二行 = 4 号点能否到达各点)

(1 分)
第 66 题 K4 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    int n = 3;
05    int d[4][4];
06    memset(d, 0x3f, sizeof d);
07    for (int i = 1; i <= n; i++) d[i][i] = 0;
08    d[1][2] = 1; d[2][3] = -1; d[3][1] = -1;
09    for (int k = 1; k <= n; k++)
10        for (int i = 1; i <= n; i++)
11            for (int j = 1; j <= n; j++)
12                d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
13    bool neg = false;
14    for (int i = 1; i <= n; i++)
15        if (d[i][i] < 0) neg = true;
16    cout << (neg ? "YES" : "NO");
17    return 0;
18}

单选题:程序输出是?

(1 分)
第 67 题 K5 未作答

01for (int k = 1; k <= n; k++)
02    for (int i = 1; i <= n; i++)
03        for (int j = 1; j <= n; j++)
04            d[i][j] = min(d[i][j], ______);   // 以 k 为中转点

单选题:横线处应填入?

(1 分)
第 68 题 K6 未作答

01// 图同 K1:4 个点的有向图,求任意两点间最短路
02// 问:d[2][4] 最终的值是多少?
03int d[5][5];
04memset(d, 0x3f, sizeof d);
05for (int i = 1; i <= 4; i++) d[i][i] = 0;
06d[1][2] = 2; d[1][3] = 5; d[2][3] = 1; d[2][4] = 6; d[3][4] = 2;
07for (int k = 1; k <= 4; k++)
08    for (int i = 1; i <= 4; i++)
09        for (int j = 1; j <= 4; j++)
10            d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
11cout << d[2][4];

单选题:程序输出是?

(1 分)
第 69 题 K7 未作答

01#include <bits/stdc++.h>
02using namespace std;
03const int INF = 0x3f3f3f3f;
04int main() {
05    int n = 4;
06    int d[5][5];
07    memset(d, 0x3f, sizeof d);
08    for (int i = 1; i <= n; i++) d[i][i] = 0;
09    d[1][2] = 2; d[1][3] = 5; d[2][3] = 1; d[2][4] = 6; d[3][4] = 2;
10    for (int k = 1; k <= n; k++)
11        for (int i = 1; i <= n; i++)
12            for (int j = 1; j <= n; j++)
13                d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
14    for (int i = 1; i <= 2; i++) {          // 只输出前两行
15        for (int j = 1; j <= n; j++) {
16            if (d[i][j] == INF) cout << "INF"; else cout << d[i][j];
17            cout << " ";
18        }
19        cout << endl;
20    }
21    return 0;
22}

单选题:程序输出是?

(1 分)
拾贰

次短路代码

6 QUESTIONS · 2 POINTS EACH
第 70 题 L1 未作答

01#include <bits/stdc++.h>
02using namespace std;
03const int INF = 0x3f3f3f3f;
04int main() {
05    int n = 4;
06    vector<pair<int,int>> g[5];
07    g[1].push_back({2, 2}); g[1].push_back({3, 5});
08    g[2].push_back({3, 1}); g[2].push_back({4, 6});
09    g[3].push_back({4, 2});
10    int dist1[5], dist2[5];            // 最短路 与 次短路
11    for (int i = 1; i <= n; i++) dist1[i] = dist2[i] = INF;
12    dist1[1] = 0;
13    priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> q;
14    q.push({0, 1});
15    while (!q.empty()) {
16        auto [d, u] = q.top(); q.pop();
17        if (d > dist2[u]) continue;
18        for (auto [v, w] : g[u]) {
19            int nd = d + w;
20            if (nd < dist1[v]) {
21                dist2[v] = dist1[v];
22                dist1[v] = nd;
23                q.push({nd, v});
24            } else if (nd > dist1[v] && nd < dist2[v]) {
25                dist2[v] = nd;
26                q.push({nd, v});
27            }
28        }
29    }
30    cout << dist2[4];
31    return 0;
32}

单选题:程序输出是?(4 号点的次短路长度,要求严格大于最短路)

(1 分)
第 71 题 L2 未作答

// 代码与 L1 完全相同,只是最后输出改为:
cout << dist1[3] << " " << dist2[3];

单选题:程序输出是?

(1 分)
第 72 题 L3 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    int n = 4;
05    vector<pair<int,int>> g[5];
06    g[1].push_back({2, 2}); g[1].push_back({3, 5});
07    g[2].push_back({3, 1}); g[2].push_back({4, 6});
08    g[3].push_back({4, 2});
09    int dist[2][5];                    // 第 0 层:没用免费;第 1 层:已用免费
10    memset(dist, 0x3f, sizeof dist);
11    dist[0][1] = 0;
12    // (距离, 已免费用掉的边数, 点)
13    priority_queue<tuple<int,int,int>, vector<tuple<int,int,int>>, greater<>> q;
14    q.push({0, 0, 1});
15    while (!q.empty()) {
16        auto [d, f, u] = q.top(); q.pop();
17        if (d > dist[f][u]) continue;
18        for (auto [v, w] : g[u]) {
19            if (dist[f][v] > d + w) {         // 本条边正常付费
20                dist[f][v] = d + w;
21                q.push({d + w, f, v});
22            }
23            if (f == 0 && dist[1][v] > d) {   // 本条边免费(至多用一次)
24                dist[1][v] = d;
25                q.push({d, 1, v});
26            }
27        }
28    }
29    cout << dist[1][4];
30    return 0;
31}

单选题:程序输出是?(至多把一条边的费用改为 0,1 到 4 的最小费用)

(1 分)
第 73 题 L4 未作答

01int nd = d + w;
02if (nd < dist1[v]) {
03    dist2[v] = dist1[v];
04    dist1[v] = nd;
05    q.push({nd, v});
06} else if (nd > dist1[v] && nd < dist2[v]) {
07    ______;              // 更新次短路
08    q.push({nd, v});
09}

单选题:横线处应填入?

(1 分)
第 74 题 L5 未作答

// 图在 L1 基础上加一条边:1 -> 4,边权 4
g[1].push_back({4, 4});
// 其余代码与 L1 完全相同,最后输出 dist2[4]

单选题:程序输出是?(此时最短路为 4,次短路严格大于 4)

(1 分)
第 75 题 L6 未作答

01// 代码与 L1 完全相同,最后输出 1~4 号点的次短路(INF 输出 INF):
02for (int i = 1; i <= n; i++) {
03    if (dist2[i] == INF) cout << "INF"; else cout << dist2[i];
04    cout << " ";
05}

单选题:程序输出是?

(1 分)
拾叁

最短路应用代码

6 QUESTIONS · 2 POINTS EACH
第 76 题 M1 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    int n = 4, s = 1, t = 4;
05    vector<pair<int,int>> g[5];
06    g[1].push_back({2, 2}); g[1].push_back({3, 5});
07    g[2].push_back({3, 1}); g[2].push_back({4, 6});
08    g[3].push_back({4, 2});
09    int dist[5], pre[5], vis[5] = {0};
10    memset(dist, 0x3f, sizeof dist);
11    dist[s] = 0;
12    priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> q;
13    q.push({0, s});
14    while (!q.empty()) {
15        auto [d, u] = q.top(); q.pop();
16        if (vis[u]) continue;
17        vis[u] = 1;
18        for (auto [v, w] : g[u])
19            if (dist[v] > d + w) {
20                dist[v] = d + w;
21                pre[v] = u;              // 记录前驱
22                q.push({dist[v], v});
23            }
24    }
25    vector<int> path;
26    for (int x = t; x != s; x = pre[x]) path.push_back(x);
27    path.push_back(s);
28    reverse(path.begin(), path.end());
29    for (int x : path) cout << x << " ";
30    return 0;
31}

单选题:程序输出是?(1 到 4 的最短路径)

(1 分)
第 77 题 M2 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    int n = 4;
05    vector<pair<int,int>> g[5];
06    g[1].push_back({2, 2}); g[1].push_back({3, 5}); g[1].push_back({4, 5});
07    g[2].push_back({3, 1}); g[2].push_back({4, 6});
08    g[3].push_back({4, 2});
09    int dist[5], cnt[5], vis[5] = {0};
10    memset(dist, 0x3f, sizeof dist);
11    memset(cnt, 0, sizeof cnt);
12    dist[1] = 0; cnt[1] = 1;
13    priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> q;
14    q.push({0, 1});
15    while (!q.empty()) {
16        auto [d, u] = q.top(); q.pop();
17        if (vis[u]) continue;
18        vis[u] = 1;
19        for (auto [v, w] : g[u]) {
20            int nd = d + w;
21            if (nd < dist[v]) {
22                dist[v] = nd;
23                cnt[v] = cnt[u];         // 继承计数
24                q.push({nd, v});
25            } else if (nd == dist[v]) {
26                cnt[v] += cnt[u];        // 等长路径累加
27            }
28        }
29    }
30    cout << cnt[4];
31    return 0;
32}

单选题:程序输出是?(1 到 4 的最短路条数)

(1 分)
第 78 题 M3 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    int n = 4;
05    bool r[5][5] = {};
06    r[1][2] = r[1][3] = r[2][3] = r[2][4] = r[3][4] = true;
07    for (int k = 1; k <= n; k++)
08        for (int i = 1; i <= n; i++)
09            for (int j = 1; j <= n; j++)
10                r[i][j] = r[i][j] || (r[i][k] && r[k][j]);
11    int cnt = 0;
12    for (int i = 1; i <= n; i++)
13        for (int j = 1; j <= n; j++)
14            if (i != j && r[i][j]) cnt++;
15    cout << cnt;
16    return 0;
17}

单选题:程序输出是?(i 能到达 j 的有序点对数,i ≠ j)

(1 分)
第 79 题 M4 未作答

01int nd = d + w;
02if (nd < dist[v]) {
03    dist[v] = nd;
04    cnt[v] = cnt[u];
05    q.push({nd, v});
06} else if (nd == dist[v]) {
07    ______;              // 等长路径,计数累加
08}

单选题:横线处应填入?

(1 分)
第 80 题 M5 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    int n = 4, s = 4;
05    vector<pair<int,int>> g[5];        // 反向建图:原边 u->v 变为 v->u
06    g[2].push_back({1, 2});
07    g[3].push_back({1, 5});
08    g[3].push_back({2, 1});
09    g[4].push_back({2, 6});
10    g[4].push_back({3, 2});
11    int dist[5], vis[5] = {0};
12    memset(dist, 0x3f, sizeof dist);
13    dist[s] = 0;
14    priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> q;
15    q.push({0, s});
16    while (!q.empty()) {
17        auto [d, u] = q.top(); q.pop();
18        if (vis[u]) continue;
19        vis[u] = 1;
20        for (auto [v, w] : g[u])
21            if (dist[v] > d + w) {
22                dist[v] = d + w;
23                q.push({dist[v], v});
24            }
25    }
26    cout << dist[1];
27    return 0;
28}

单选题:程序输出是?(等价于原图 1 到 4 的最短路)

(1 分)
第 81 题 M6 未作答

// 图同 M2(含边 1->4 权 5),Dijkstra 同时维护 dist 与 cnt,
// 最后输出:
cout << dist[4] << " " << cnt[4];

单选题:程序输出是?

(1 分)
拾肆

综合代码

6 QUESTIONS · 2 POINTS EACH
第 82 题 N1 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    int n = 4;
05    vector<pair<int,int>> g[5];
06    g[1].push_back({2, 2}); g[1].push_back({3, 5});
07    g[2].push_back({3, 1}); g[2].push_back({4, 6});
08    g[3].push_back({4, 2});
09    int dist[5], vis[5] = {0};
10    memset(dist, 0x3f, sizeof dist);
11    dist[1] = 0;
12    priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> q;
13    q.push({0, 1});
14    while (!q.empty()) {
15        auto [d, u] = q.top(); q.pop();
16        if (vis[u]) continue;
17        vis[u] = 1;
18        for (auto [v, w] : g[u])
19            if (dist[v] > d + w) {
20                dist[v] = d + w;
21                q.push({dist[v], v});
22            }
23    }
24    for (int i = 1; i <= n; i++) cout << dist[i] << " ";
25    return 0;
26}

单选题:程序输出是?

(1 分)
第 83 题 N2 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    int n = 3;
05    vector<pair<int,int>> g[4];
06    g[1].push_back({2, 2}); g[1].push_back({3, 3});
07    g[2].push_back({3, -1});
08    int dist[4], inq[4] = {0};
09    memset(dist, 0x3f, sizeof dist);
10    dist[1] = 0;
11    queue<int> q;
12    q.push(1); inq[1] = 1;
13    while (!q.empty()) {
14        int u = q.front(); q.pop();
15        inq[u] = 0;
16        for (auto [v, w] : g[u])
17            if (dist[v] > dist[u] + w) {
18                dist[v] = dist[u] + w;
19                if (!inq[v]) { q.push(v); inq[v] = 1; }
20            }
21    }
22    cout << dist[3];
23    return 0;
24}

单选题:程序输出是?(SPFA 处理含负权边的图)

(1 分)
第 84 题 N3 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    int n = 4;
05    int d[5][5];
06    memset(d, 0x3f, sizeof d);
07    for (int i = 1; i <= n; i++) d[i][i] = 0;
08    d[1][2] = 2; d[1][3] = 5; d[2][3] = 1; d[2][4] = 6; d[3][4] = 2;
09    for (int k = 1; k <= n; k++)
10        for (int i = 1; i <= n; i++)
11            for (int j = 1; j <= n; j++)
12                d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
13    cout << d[1][3] << " " << d[2][4];
14    return 0;
15}

单选题:程序输出是?

(1 分)
第 85 题 N4 未作答

// 图同 L1,双重 dist 的 Dijkstra,最后输出:
cout << dist1[4] << " " << dist2[4];

单选题:程序输出是?

(1 分)
第 86 题 N5 未作答

01for (int r = 1; r <= n - 1; r++)
02    for (auto [u, v, w] : e)
03        if (______)
04            dist[v] = dist[u] + w;

单选题:横线处应填入?

(1 分)
第 87 题 N6 未作答

// SPFA + 入队次数判负环,图同 J4(含负权边但无负环)
// 最后输出:
cout << dist[1] << " " << dist[2] << " " << dist[3] << endl;
cout << "NO";

单选题:程序输出是?

(1 分)
拾伍

完善程序

7 QUESTIONS · 2 POINTS EACH
第 88 题 O1 未作答

01int n, m, dist[N], vis[N];
02vector<pair<int,int>> g[N];
03priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> q;
04
05void dijkstra(int s) {
06    memset(dist, 0x3f, sizeof dist);
07    memset(vis, 0, sizeof vis);
08    dist[s] = 0;
09    q.push({0, s});
10    while (!q.empty()) {
11        auto [d, u] = ①;     // 取出当前距离最小的点
12        q.pop();
13        if (vis[u]) continue;
14        vis[u] = 1;
15        for (auto [v, w] : g[u])
16            if (dist[v] > d + w) {
17                dist[v] = d + w;
18                q.push({dist[v], v});
19            }
20    }
21}

单选题:①处应填?

(1 分)
第 89 题 O2 未作答

01// edges 存所有边 (u, v, w),n 为点数
02for (int i = 1; i <= ①; i++)          // 松弛 n-1 轮
03    for (auto [u, v, w] : edges)
04        if (dist[v] > dist[u] + w)
05            dist[v] = dist[u] + w;

单选题:①处应填?

(1 分)
第 90 题 O3 未作答

01while (!q.empty()) {
02    int u = q.front(); q.pop();
03    ①;                            // 出队后清除入队标记
04    for (auto [v, w] : g[u])
05        if (dist[v] > dist[u] + w) {
06            dist[v] = dist[u] + w;
07            if (!inq[v]) {
08                q.push(v);
09                inq[v] = 1;
10            }
11        }
12}

单选题:①处应填?

(1 分)
第 91 题 O4 未作答

01for (int k = 1; k <= n; k++)
02    for (int i = 1; i <= n; i++)
03        for (int j = 1; j <= n; j++)
04            d[i][j] = min(d[i][j], ②);   // 以 k 为中转点

单选题:②处应填?

(1 分)
第 92 题 O5 未作答

01while (!q.empty()) {
02    auto [d, u] = q.top(); q.pop();
03    if (d > dist2[u]) continue;
04    for (auto [v, w] : g[u]) {
05        int nd = d + w;
06        if (nd < dist1[v]) {
07            dist2[v] = dist1[v];
08            dist1[v] = nd;
09            q.push({nd, v});
10        } else if (nd > dist1[v] && nd < dist2[v]) {
11            ①;                  // 更新次短路
12            q.push({nd, v});
13        }
14    }
15}

单选题:①处应填?

(1 分)
第 93 题 O6 未作答

01// SPFA 中松弛成功时:
02cnt[v] = ①;                    // 记录 v 的松弛次数
03if (cnt[v] > n) { cout << "YES"; return 0; }

单选题:①处应填?

(1 分)
第 94 题 O7 未作答

01for (auto [v, w] : g[u])
02    if (dist[v] > d + w) {
03        dist[v] = d + w;
04        ①;                   // 记录 v 的前驱
05        q.push({dist[v], v});
06    }
07// 输出路径:从终点 t 沿 pre 倒推回起点 s

单选题:①处应填?

(1 分)
拾陆

代码易错

6 QUESTIONS · 2 POINTS EACH
第 95 题 P1 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    int n = 4;
05    int w[5][5];
06    memset(w, 0x3f, sizeof w);
07    w[1][2] = 2; w[1][3] = 5; w[2][3] = 1; w[2][4] = 6; w[3][4] = 2;
08    int dist[5], vis[5] = {0};
09    memset(dist, 0x3f, sizeof dist);
10    dist[1] = 0;
11    for (int it = 0; it < n; it++) {
12        int u = -1;
13        for (int i = 1; i <= n; i++)
14            if (!vis[i] && (u == -1 || dist[i] < dist[u])) u = i;
15        // 注意:这里漏掉了 vis[u] = 1;
16        for (int v = 1; v <= n; v++)
17            if (w[u][v] != 0x3f3f3f3f && dist[v] > dist[u] + w[u][v])
18                dist[v] = dist[u] + w[u][v];
19    }
20    for (int i = 1; i <= n; i++) cout << dist[i] << " ";
21    return 0;
22}

单选题:程序输出是?(正确结果应为 0 2 3 5

(1 分)
第 96 题 P2 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    int n = 5;
05    int d[6][6];
06    memset(d, 0x3f, sizeof d);
07    for (int i = 1; i <= n; i++) d[i][i] = 0;
08    d[1][3] = 1; d[3][4] = 1; d[4][2] = 1; d[2][5] = 1; d[1][5] = 10;
09    for (int i = 1; i <= n; i++)       // 注意:k 被放到了最内层
10        for (int j = 1; j <= n; j++)
11            for (int k = 1; k <= n; k++)
12                d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
13    cout << d[1][5];
14    return 0;
15}

单选题:程序输出是?(正确 Floyd 的结果应为 4

(1 分)
第 97 题 P3 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    int n = 4;
05    vector<pair<int,int>> g[5];
06    g[1].push_back({3, 3}); g[1].push_back({2, 2});   // 注意边的顺序
07    g[2].push_back({3, -1});
08    g[3].push_back({4, 1});
09    int dist[5], inq[5] = {0};
10    memset(dist, 0x3f, sizeof dist);
11    dist[1] = 0;
12    queue<int> q;
13    q.push(1); inq[1] = 1;
14    while (!q.empty()) {
15        int u = q.front(); q.pop();
16        // 注意:这里漏掉了 inq[u] = 0;
17        for (auto [v, w] : g[u])
18            if (dist[v] > dist[u] + w) {
19                dist[v] = dist[u] + w;
20                if (!inq[v]) { q.push(v); inq[v] = 1; }
21            }
22    }
23    cout << dist[4];
24    return 0;
25}

单选题:程序输出是?(正确结果应为 2

(1 分)
第 98 题 P4 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    int n = 4;
05    int w[5][5];
06    memset(w, 0x3f, sizeof w);
07    w[1][2] = 2; w[1][3] = 5; w[2][3] = 1; w[2][4] = 6; w[3][4] = 2;
08    int dist[5], vis[5] = {0};
09    memset(dist, 0, sizeof dist);   // 错误:dist 全部初始化成了 0
10    // 朴素 Dijkstra 部分与 I1 完全相同……
11    for (int i = 1; i <= n; i++) cout << dist[i] << " ";
12    return 0;
13}

单选题:程序输出是?(正确结果应为 0 2 3 5

(1 分)
第 99 题 P5 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    int n = 4;
05    vector<pair<int,int>> g[5];
06    g[1].push_back({2, 2}); g[1].push_back({3, 3});
07    g[2].push_back({4, 1});
08    g[3].push_back({2, -4}); g[3].push_back({4, 2});
09    int dist[5], vis[5] = {0};
10    memset(dist, 0x3f, sizeof dist);
11    dist[1] = 0;
12    priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> q;
13    q.push({0, 1});
14    while (!q.empty()) {
15        auto [d, u] = q.top(); q.pop();
16        if (vis[u]) continue;
17        vis[u] = 1;
18        for (auto [v, w] : g[u])
19            if (dist[v] > d + w) {
20                dist[v] = d + w;
21                q.push({dist[v], v});
22            }
23    }
24    cout << dist[4];
25    return 0;
26}

单选题:程序输出是?(图含负权边,真正的最短路应为 0

(1 分)
第 100 题 P6 未作答

判断题:以下五种易错写法都会导致程序出错——①Dijkstra 忘写 vis[u] = 1(反复选起点)②Floyd 的 k 放在最内层(可能得到错误距离)③SPFA 出队后忘清 inq[u](可能漏更新)④dist 错误地全初始化为 0 ⑤负权图用 Dijkstra(可能得到错误答案)。

(1 分)