林老师 · 客观题题库 · 第 32 章 MST与拓扑排序 · 知识细节练习

第 32 章 MST与拓扑排序 · 知识细节练习

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

判 分 报 告

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

MST 基础

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

最小生成树(MST)的定义是?

(1 分)
第 2 题 A2 未作答

判断题:nn 个点的生成树恰有 n1n-1 条边,且连通、无环。

(1 分)
第 3 题 A3 未作答

判断题:最小生成树在任何情况下都一定唯一。

(1 分)
第 4 题 A4 未作答

MST 的典型应用是?

(1 分)
第 5 题 A5 未作答

判断题:MST 保证的是全局连通代价最小;它不保证任意两点之间的路径是该两点的最短路。

(1 分)
第 6 题 A6 未作答

MST 两算法总表是?

(1 分)

Prim

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

Prim 的核心思想是?

(1 分)
第 8 题 B2 未作答

Prim 的步骤是?

(1 分)
第 9 题 B3 未作答

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

(1 分)
第 10 题 B4 未作答

Prim 与 Dijkstra 的关键区别是?

(1 分)
第 11 题 B5 未作答

判断题:Prim 每次取跨集合的最小边——贪心正确性来自割性质(任一切割的最小边必在某棵 MST 中)。

(1 分)
第 12 题 B6 未作答

判断题:稠密图(mm 接近 n2n^2)首选朴素 Prim——O(n2)O(n^2) 反优于堆优化版的 O(mlogn)O(m \log n)

(1 分)
第 13 题 B7 未作答

判断题:Prim/Kruskal 只适用于边权非负的图,出现负权边就失效。

(1 分)

Kruskal

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

Kruskal 的核心思想是?

(1 分)
第 15 题 C2 未作答

Kruskal 的步骤是?

(1 分)
第 16 题 C3 未作答

Kruskal 用并查集判环的方法是?

(1 分)
第 17 题 C4 未作答

Kruskal 的复杂度是?

(1 分)
第 18 题 C5 未作答

判断题:Kruskal 每次选"不构成环的最小边"——贪心正确(环性质:环上最大边不属于 MST)。

(1 分)
第 19 题 C6 未作答

判断题:Kruskal 适合稀疏图且依赖并查集;Prim 适合稠密图且长得像 Dijkstra——两者殊途同归。

(1 分)
第 20 题 C7 未作答

判断题:Kruskal 必须先按边权升序排序——不排序直接取边,贪心就会失效。

(1 分)

拓扑排序

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

拓扑排序的前提是?

(1 分)
第 22 题 D2 未作答

入度的定义是?

(1 分)
第 23 题 D3 未作答

Kahn(BFS 版)拓扑排序的步骤是?

(1 分)
第 24 题 D4 未作答

判断题:Kahn 结束时输出点数 <n< n ⟺ 图中有环(环上点的入度永远不为 0)。

(1 分)
第 25 题 D5 未作答

判断题:DAG 的拓扑序一定唯一。

(1 分)
第 26 题 D6 未作答

判断题:DFS 版拓扑排序 = 对每个未访问点做 DFS,后序(离开时)压入结果,最后反转;递归栈中遇到回边则判有环。

(1 分)
第 27 题 D7 未作答

拓扑排序的典型应用是?

(1 分)

MST 应用

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

判断题:n 个城市用最少的电缆总长连通 = 求 MST——布线是 MST 的经典原型。

(1 分)
第 29 题 E2 未作答

最大生成树的求法是?

(1 分)
第 30 题 E3 未作答

判断题:次小生成树思想——枚举替换 MST 上的一条边,换成不连成环的次优边,取总代价最小者。

(1 分)
第 31 题 E4 未作答

判断题:MST 上两点路径的最大边权 = 这两点间"最小化最大边权"路径(瓶颈路)的最优解。

(1 分)
第 32 题 E5 未作答

判断题:MST 变体——生成树计数、带重边取最小、边权相等时多解——都以基本两算法为基础扩展。

(1 分)
第 33 题 E6 未作答

判断题:MST(Prim/Kruskal)定义在无向连通图上;有向图的最小树形图是另一个问题。

(1 分)

拓扑应用

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

判断题:课程先修关系建模成 DAG——先修课指向后修课,拓扑序就是合法选课顺序。

(1 分)
第 35 题 F2 未作答

判断题:依赖关系成环 = 依赖冲突(如 A 依赖 B、B 依赖 A)——拓扑判环即可检测。

(1 分)
第 36 题 F3 未作答

判断题:DAG 上 DP 按拓扑序做——处理点 uu 时其所有前驱已计算完,转移正确。

(1 分)
第 37 题 F4 未作答

判断题:DAG 上求最长路(AOE 关键路径思想)——把最短路 DP 的 min 换成 max,在拓扑序上做。

(1 分)
第 38 题 F5 未作答

字典序最小拓扑序用?

(1 分)
第 39 题 F6 未作答

判断题:拓扑排序是"DAG 上的调度语言"——判环、排序、DP 顺序三合一。

(1 分)

算法选择

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

Prim/Kruskal/拓扑排序总表是?

(1 分)
第 41 题 G2 未作答

n500n \le 500mn2m \approx n^2 的稠密图求 MST,选?

(1 分)
第 42 题 G3 未作答

判断题:判环工具选择——无向图用并查集或 DFS;有向图用拓扑排序或 DFS 三色标记。

(1 分)
第 43 题 G4 未作答

"边数很少(稀疏图)+ 求 MST",选?

(1 分)
第 44 题 G5 未作答

判断题:MST 与最短路目标不同——别拿 Dijkstra 求 MST、也别拿 MST 求两点最短路。

(1 分)
第 45 题 G6 未作答

判断题:选择流程——求全局连通最小代价用 MST(稠密 Prim/稀疏 Kruskal);求依赖顺序/判有向环用拓扑;求两点路径用最短路。

(1 分)

易错综合

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

判断题:Kruskal 忘判环(不做 find 检查直接 union)会得到带环的"树"——结果不再是生成树。

(1 分)
第 47 题 H2 未作答

判断题:Kahn 拓扑忘写"出边终点入度减 1",队列只会输出最初入度 0 的点——结果严重不全。

(1 分)
第 48 题 H3 未作答

判断题:Prim 的更新式是 d[v]=min(d[v],w)d[v] = \min(d[v], w);若误写成 Dijkstra 的 d[u]+wd[u]+w,MST 代价会算错。

(1 分)
第 49 题 H4 未作答

判断题:重边保留最小权即可(Kruskal 排序后天然处理);自环不可能是 MST 边,Kruskal 判环时自动跳过。

(1 分)
第 50 题 H5 未作答

判断题:以下结论全部正确——"生成树 n1n-1 条边;Prim 的 d 是到集合的最小边权;Kruskal 先排序再并查集判环;拓扑 Kahn 入度 0 入队、输出 <n< n 判环;MST 不保证两点最短路"。

(1 分)

Prim 代码

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

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] = w[2][1] = 2; w[1][3] = w[3][1] = 5;
08    w[2][3] = w[3][2] = 1; w[2][4] = w[4][2] = 6;
09    w[3][4] = w[4][3] = 2;
10    int d[5], vis[5] = {0};
11    memset(d, 0x3f, sizeof d);
12    d[1] = 0;
13    int ans = 0;
14    for (int it = 0; it < n; it++) {
15        int u = -1;
16        for (int i = 1; i <= n; i++)
17            if (!vis[i] && (u == -1 || d[i] < d[u])) u = i;
18        vis[u] = 1;
19        ans += d[u];
20        for (int v = 1; v <= n; v++)
21            if (!vis[v] && w[u][v] != 0x3f3f3f3f && d[v] > w[u][v])
22                d[v] = w[u][v];
23    }
24    cout << ans;
25    return 0;
26}

单选题:程序输出是?(MST 总代价)

(1 分)
第 52 题 I2 未作答

// 图与 I1 完全相同,循环体内在 vis[u] = 1 之后加一句:
cout << u << " ";

单选题:程序输出是?(点加入树的顺序)

(1 分)
第 53 题 I3 未作答

01// 图与 I1 完全相同,最后输出 d 数组:
02for (int i = 1; i <= n; i++) cout << d[i] << " ";

单选题:程序输出是?(d[i] = 点 i 加入时的代价,即到已选集合的最小边权)

(1 分)
第 54 题 I4 未作答

01// 图与 I1 完全相同,循环体内在 vis[u] = 1 后加:
02if (u == 2) {                       // 刚加入 2 号点时
03    for (int i = 1; i <= n; i++) cout << d[i] << " ";
04}

单选题:程序输出是?

(1 分)
第 55 题 I5 未作答

01vis[u] = 1;
02ans += d[u];
03for (int v = 1; v <= n; v++)
04    if (w[u][v] != 0x3f3f3f3f && d[v] > ______)
05        d[v] = ______;              // 用边权直接更新

单选题:横线处应填入?

(1 分)
第 56 题 I6 未作答

// 图与 I1 基本相同,只有 3-4 这条边权改成 3:
w[3][4] = w[4][3] = 3;

单选题:程序输出是?(MST 总代价)

(1 分)

Kruskal 代码

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

01#include <bits/stdc++.h>
02using namespace std;
03struct Edge { int u, v, w; };
04int fa[5];
05int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
06int main() {
07    int n = 4;
08    vector<Edge> e = {{1,2,2}, {1,3,5}, {2,3,1}, {2,4,6}, {3,4,2}};
09    sort(e.begin(), e.end(), [](Edge a, Edge b) { return a.w < b.w; });
10    for (int i = 1; i <= n; i++) fa[i] = i;
11    int ans = 0;
12    for (auto [u, v, w] : e) {
13        if (find(u) != find(v)) {
14            fa[find(u)] = find(v);
15            ans += w;
16        }
17    }
18    cout << ans;
19    return 0;
20}

单选题:程序输出是?

(1 分)
第 58 题 J2 未作答

01// 图与 J1 完全相同,取边时输出该边权值:
02if (find(u) != find(v)) {
03    fa[find(u)] = find(v);
04    cout << w << " ";
05}

单选题:程序输出是?(被选入 MST 的边的权值序列)

(1 分)
第 59 题 J3 未作答

01#include <bits/stdc++.h>
02using namespace std;
03struct Edge { int u, v, w; };
04int fa[5];
05int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
06int main() {
07    int n = 4;
08    vector<Edge> e = {{1,2,2}, {2,3,1}, {3,4,2}, {1,4,3}, {1,3,5}};
09    sort(e.begin(), e.end(), [](Edge a, Edge b) { return a.w < b.w; });
10    for (int i = 1; i <= n; i++) fa[i] = i;
11    int skip = 0;
12    for (auto [u, v, w] : e) {
13        if (find(u) != find(v)) fa[find(u)] = find(v);
14        else skip++;                 // 两端已连通,成环跳过
15    }
16    cout << skip;
17    return 0;
18}

单选题:程序输出是?(被跳过(会成环)的边数)

(1 分)
第 60 题 J4 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[5] = {0, 2, 3, 4, 4};   // 链:1 -> 2 -> 3 -> 4
04int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
05int main() {
06    find(1);                    // 查找 1 的代表元,触发路径压缩
07    cout << fa[1] << " " << fa[2] << " " << fa[3];
08    return 0;
09}

单选题:程序输出是?

(1 分)
第 61 题 J5 未作答

01for (auto [u, v, w] : e) {
02    if (find(u) != find(v)) {
03        ______;              // 合并两集合
04        ans += w;
05    }
06}

单选题:横线处应填入?

(1 分)
第 62 题 J6 未作答

// 图与 J1 完全相同,取边时 cnt++,最后输出:
cout << cnt << " " << ans;

单选题:程序输出是?(取边数与总代价)

(1 分)
拾壹

拓扑排序代码

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

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

单选题:程序输出是?(拓扑序)

(1 分)
第 64 题 K2 未作答

// 图与 K1 的唯一区别:1 号点的邻接顺序不同——
g[1].push_back(3);
g[1].push_back(2);

单选题:程序输出是?(换邻接顺序后队列顺序改变,拓扑序合法但不同)

(1 分)
第 65 题 K3 未作答

01// 图与 K1 完全相同,每出队一个点后输出 indeg[4]:
02while (!q.empty()) {
03    int u = q.front(); q.pop();
04    for (int v : g[u])
05        if (--indeg[v] == 0) q.push(v);
06    cout << indeg[4] << " ";
07}

单选题:程序输出是?(每出队一个点后 4 号点的入度)

(1 分)
第 66 题 K4 未作答

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

单选题:程序输出是?

(1 分)
第 67 题 K5 未作答

01int u = q.front(); q.pop();
02cnt++;
03for (int v : g[u]) {
04    if (______ == 0) q.push(v);   // 入度减 1 后为 0 才入队
05}

单选题:横线处应填入?

(1 分)
第 68 题 K6 未作答

01// 图与 K1 完全相同,只是队列换成小根堆:
02priority_queue<int, vector<int>, greater<int>> q;
03for (int i = 1; i <= n; i++)
04    if (indeg[i] == 0) q.push(i);
05while (!q.empty()) {
06    int u = q.top(); q.pop();
07    cout << u << " ";
08    for (int v : g[u])
09        if (--indeg[v] == 0) q.push(v);
10}

单选题:程序输出是?(字典序最小的拓扑序)

(1 分)
第 69 题 K7 未作答

// 图与 K1 完全相同,最后输出:
cout << cnt << endl;              // cnt = 已输出的点数
// 输出顺序已在出队时打印

单选题:程序输出是?(第一行 = 输出点数,第二行 = 拓扑序)

(1 分)
拾贰

MST 应用代码

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

01#include <bits/stdc++.h>
02using namespace std;
03struct Edge { int u, v, w; };
04int fa[5];
05int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
06int main() {
07    int n = 4;
08    vector<Edge> e = {{1,2,2}, {1,3,5}, {2,3,1}, {2,4,6}, {3,4,2}};
09    sort(e.begin(), e.end(), [](Edge a, Edge b) { return a.w > b.w; });  // 降序
10    for (int i = 1; i <= n; i++) fa[i] = i;
11    int ans = 0;
12    for (auto [u, v, w] : e)
13        if (find(u) != find(v)) {
14            fa[find(u)] = find(v);
15            ans += w;
16        }
17    cout << ans;
18    return 0;
19}

单选题:程序输出是?(最大生成树总代价)

(1 分)
第 71 题 L2 未作答

01// 图与 I1 相同。最小生成树的边为 (2,3,1)、(1,2,2)、(3,4,2)。
02// 瓶颈路 = MST 上两点路径的最大边权,本题求 MST 的最大边权:
03int mx = 0;
04for (auto [u, v, w] : mstEdges) mx = max(mx, w);
05cout << mx;

单选题:程序输出是?

(1 分)
第 72 题 L3 未作答

// 思想:枚举删掉 MST 上的一条边,求剩余图的 MST,取最小总代价。
// 图边:(1,2,2) (1,3,5) (2,3,1) (2,4,6) (3,4,2),MST = {2-3:1, 1-2:2, 3-4:2} = 5
// 删 (2,3,1) → 剩余 MST = 1-2:2 + 3-4:2 + 1-3:5 = 9
// 删 (1,2,2) → 剩余 MST = 2-3:1 + 3-4:2 + 1-3:5 = 8
// 删 (3,4,2) → 剩余 MST = 2-3:1 + 1-2:2 + 2-4:6 = 9
// 次小生成树 = min(9, 8, 9) = 8
cout << 8;

单选题:程序输出是?

(1 分)
第 73 题 L4 未作答

01int cnt = 0;
02for (auto [u, v, w] : e) {
03    if (find(u) != find(v)) {
04        fa[find(u)] = find(v);
05        ans += w;
06        cnt++;
07        if (cnt == ______) break;   // 取满 n-1 条边即可停止
08    }
09}

单选题:横线处应填入?

(1 分)
第 74 题 L5 未作答

01// n = 3,只有一条边 (1,2,1):3 号点孤立,图不连通
02int n = 3;
03vector<Edge> e = {{1,2,1}};
04sort(e.begin(), e.end(), [](Edge a, Edge b) { return a.w < b.w; });
05for (int i = 1; i <= n; i++) fa[i] = i;
06int ans = 0, cnt = 0;
07for (auto [u, v, w] : e)
08    if (find(u) != find(v)) {
09        fa[find(u)] = find(v);
10        ans += w; cnt++;
11    }
12if (cnt < n - 1) cout << "IMPOSSIBLE";
13else cout << ans;

单选题:程序输出是?

(1 分)
第 75 题 L6 未作答

// 图与 J1 完全相同,最后输出:
cout << ans << " " << cnt;     // cnt = 取边数

单选题:程序输出是?

(1 分)
拾叁

拓扑应用代码

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

// 课程先修:1 先于 2、1 先于 3、2 先于 4、3 先于 4
// 图与 K1 完全相同,输出拓扑序

单选题:程序输出是?(一个合法的选课顺序)

(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    int indeg[5] = {0};
07    g[1].push_back({2, 2}); g[1].push_back({3, 3});
08    g[2].push_back({4, 4});
09    g[3].push_back({4, 1});
10    for (int u = 1; u <= n; u++)
11        for (auto [v, w] : g[u]) indeg[v]++;
12    queue<int> q;
13    for (int i = 1; i <= n; i++) if (indeg[i] == 0) q.push(i);
14    int dist[5] = {0};
15    while (!q.empty()) {
16        int u = q.front(); q.pop();
17        for (auto [v, w] : g[u]) {
18            dist[v] = max(dist[v], dist[u] + w);   // 拓扑序 DP 求最长路
19            if (--indeg[v] == 0) q.push(v);
20        }
21    }
22    cout << dist[4];
23    return 0;
24}

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

(1 分)
第 78 题 M3 未作答

// 依赖关系成环:1 依赖 2、2 依赖 3、3 依赖 1(边 1<-2, 2<-3, 3<-1)
// 建边 2->1, 3->2, 1->3 后 Kahn 输出点数 < n,输出:
cout << "NO";

单选题:程序输出是?(存在循环依赖)

(1 分)
第 79 题 M4 未作答

01for (auto [v, w] : g[u]) {
02    dist[v] = max(dist[v], ______);   // 经 u 到 v 的更长路
03    if (--indeg[v] == 0) q.push(v);
04}

单选题:横线处应填入?

(1 分)
第 80 题 M5 未作答

// 图与 M2 相同(先修关系不变),用小根堆求字典序最小拓扑序

单选题:程序输出是?

(1 分)
第 81 题 M6 未作答

01// 图与 M2 完全相同(含边权),拓扑序 DP 求最长路后输出整个 dist:
02for (int i = 1; i <= n; i++) cout << dist[i] << " ";

单选题:程序输出是?

(1 分)
拾肆

综合代码

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

// 图与 I1 完全相同,但起点换成 2(d[2] = 0):

单选题:程序输出是?(MST 总代价与起点无关)

(1 分)
第 83 题 N2 未作答

// 图与 J1 完全相同(标准 Kruskal),输出总代价

单选题:程序输出是?

(1 分)
第 84 题 N3 未作答

01#include <bits/stdc++.h>
02using namespace std;
03vector<int> g[5];
04int vis[5];
05void dfs(int u) {                  // DFS 版拓扑排序:后序压栈
06    vis[u] = 1;
07    for (int v : g[u]) if (!vis[v]) dfs(v);
08    cout << u << " ";              // 后序:离开时输出
09}
10int main() {
11    g[1].push_back(2); g[1].push_back(3);
12    g[2].push_back(4);
13    g[3].push_back(4);
14    dfs(1);
15    return 0;
16}

单选题:程序输出是?(后序输出的逆序才是拓扑序;本题直接问后序输出)

(1 分)
第 85 题 N4 未作答

// 同一张无向图(边同 I1):先 Kruskal 求 MST 代价,再 Dijkstra 求 1 到 4 最短路:
cout << mstCost << " " << dist[4];

单选题:程序输出是?

(1 分)
第 86 题 N5 未作答

01sort(e.begin(), e.end(), [](Edge a, Edge b) {
02    return ______;               // 按边权升序
03});

单选题:横线处应填入?

(1 分)
第 87 题 N6 未作答

// 图:4 个点,边 (1,2,2) (2,3,1) (3,4,2) (1,3,5) (2,4,6) 外加一条重边 (1,3,7)
// 标准 Kruskal,统计 skip(判环跳过的边数)与 ans,输出:
cout << skip << " " << ans;

单选题:程序输出是?

(1 分)
拾伍

完善程序

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

01int n, m;
02int w[N][N], d[N], vis[N];
03
04int prim(int s) {
05    memset(d, 0x3f, sizeof d);
06    memset(vis, 0, sizeof vis);
07    d[s] = 0;
08    int ans = 0;
09    for (int it = 0; it < n; it++) {
10        int u = -1;
11        for (int i = 1; i <= n; i++)
12            if (!vis[i] && (u == -1 || ①)) u = i;   // 选 d 最小的未加入点
13        vis[u] = 1;
14        ans += d[u];
15        for (int v = 1; v <= n; v++)
16            if (!vis[v] && w[u][v] != INF && d[v] > w[u][v]) d[v] = w[u][v];
17    }
18    return ans;
19}

单选题:①处应填?

(1 分)
第 89 题 O2 未作答

01vis[u] = 1;
02ans += d[u];
03for (int v = 1; v <= n; v++)
04    if (w[u][v] != INF && d[v] > ②)
05        d[v] = ②;              // 到已选集合的最小边权

单选题:②处应填?

(1 分)
第 90 题 O3 未作答

01int find(int x) {
02    return fa[x] == x ? x : ①;    // 路径压缩
03}

单选题:①处应填?

(1 分)
第 91 题 O4 未作答

01for (auto [u, v, w] : e) {
02    if (①) {                 // 两端不连通才取这条边
03        fa[find(u)] = find(v);
04        ans += w;
05    }
06}

单选题:①处应填?

(1 分)
第 92 题 O5 未作答

01queue<int> q;
02for (int i = 1; i <= n; i++)
03    if (①) q.push(i);       // 初始入度为 0 的点入队

单选题:①处应填?

(1 分)
第 93 题 O6 未作答

01int u = q.front(); q.pop();
02cnt++;
03for (int v : g[u]) {
04    ①;                    // 终点入度减 1
05    if (indeg[v] == 0) q.push(v);
06}

单选题:①处应填?

(1 分)
第 94 题 O7 未作答

01while (!q.empty()) { ... cnt++; ... }
02if (①) cout << "CYCLE";   // 输出点数不足 n,有环

单选题:①处应填?

(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] = w[2][1] = 2; w[1][3] = w[3][1] = 5;
08    w[2][3] = w[3][2] = 1; w[2][4] = w[4][2] = 6;
09    w[3][4] = w[4][3] = 2;
10    int d[5], vis[5] = {0};
11    memset(d, 0x3f, sizeof d);
12    d[1] = 0;
13    int ans = 0;
14    for (int it = 0; it < n; it++) {
15        int u = -1;
16        for (int i = 1; i <= n; i++)
17            if (!vis[i] && (u == -1 || d[i] < d[u])) u = i;
18        // 注意:这里漏掉了 vis[u] = 1;
19        ans += d[u];
20        for (int v = 1; v <= n; v++)
21            if (!vis[v] && w[u][v] != 0x3f3f3f3f && d[v] > w[u][v])
22                d[v] = w[u][v];
23    }
24    cout << ans;
25    return 0;
26}

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

(1 分)
第 96 题 P2 未作答

01// 图与 J1 完全相同,但取边时不判环,直接合并:
02for (auto [u, v, w] : e) {
03    fa[find(u)] = find(v);       // 注意:没有 if (find(u) != find(v))
04    ans += w;
05}

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

(1 分)
第 97 题 P3 未作答

01// 图与 K1 完全相同,但出队后漏写了 --indeg[v]:
02while (!q.empty()) {
03    int u = q.front(); q.pop();
04    cout << u << " ";
05    for (int v : g[u]) {
06        // 注意:漏掉了 indeg[v]--,也没有入队判断
07    }
08}

单选题:程序输出是?(正确应输出 4 个点 1 2 3 4

(1 分)
第 98 题 P4 未作答

01// 图与 I1 完全相同,但更新写成了 Dijkstra 式:
02for (int v = 1; v <= n; v++)
03    if (!vis[v] && w[u][v] != 0x3f3f3f3f && d[v] > d[u] + w[u][v])
04        d[v] = d[u] + w[u][v];       // 注意:d[u] + w 而非 w

单选题:程序输出是?(正确 MST 代价应为 5

(1 分)
第 99 题 P5 未作答

01// 图与 J1 完全相同,但排序写成了降序:
02sort(e.begin(), e.end(), [](Edge a, Edge b) { return a.w > b.w; });

单选题:程序输出是?(正确最小生成树代价应为 5

(1 分)
第 100 题 P6 未作答

判断题:以下五种易错写法都会导致程序出错——①Prim 忘写 vis[u] = 1(反复选起点)②Kruskal 不判环直接合并(结果带环)③拓扑排序忘减入度(只输出最初入度 0 的点)④Prim 误用 Dijkstra 更新式 d[u]+w(代价算错)⑤Kruskal 排序写成降序(得到最大生成树)。

(1 分)