P10434 [JOIST 2024] 间谍 3 / Spy 3

题目背景

在本题中,你需要将两个文件合并成一个文件提交。 **不要引入任何头文件**,并在文件头加入如下的内容: ```cpp #include void answer(const std::vector &); ```

题目描述

Aoi 和 Bitaro 是 JOI 国 国家情报局的间谍。这次他们的任务是对 IOI 国 进行潜入调查。Bitaro 潜入 IOI 国,而 Aoi 在 JOI 国 向 Bitaro 发出指示。 潜入前,Aoi 和 Bitaro 得到了 IOI 国 的一张地图。IOI 国 有 $N$ 个城市,编号为 $0$ 到 $N-1$。此外,IOI 国 有 $M$ 条道路,编号为 $0$ 到 $M-1$。第 $i$ 条道路($0 \le i \le M-1$)双向连接城市 $A_i$ 和城市 $B_i$,长度为 $C_i$。通过若干条道路可以在任意两座城市之间往来。Bitaro 在 IOI 国 内通过这些道路在城市间移动。另外,共有 $Q$ 个调查计划。第 $j$ 个计划($0 \le j \le Q-1$)要调查 IOI 国 的城市 $T_j$。 以上信息最初同时告知了 Aoi 和 Bitaro。随后,Bitaro 开始潜入 IOI 国。 Bitaro 设法甩开了无数追兵,击败了刺客,最终成功潜入 IOI 国 的城市 $0$。然而,由于潜入行动极其艰难,Bitaro 遗失了关于 IOI 国 的部分信息。具体而言,Bitaro 丢失了 $K$ 条道路的长度信息,即道路 $X_0, X_1, \dots, X_{K-1}$。换言之,Bitaro 已不知道 $C_{X_0}, C_{X_1}, \dots, C_{X_{K-1}}$ 的数值。注意,尽管 Bitaro 丢失了这些信息,Aoi 仍然掌握它们。 Bitaro 立刻向 Aoi 报告了他所遗失的道路长度信息是哪些。 为了完成任务,Bitaro 希望从城市 $0$ 出发,分别找到到每个被 $Q$ 个调查计划锁定的城市的最短路径。 Aoi 将向 Bitaro 发送一个只包含字符 ‘0’ 或 ‘1’ 的字符串以协助他。由于存在被截获的风险,Aoi 希望尽量减少发送的内容。 给定关于 IOI 国 的信息、调查计划以及 Bitaro 所遗失信息的道路,请编写程序实现 Aoi 的发送策略;同时,编写程序实现 Bitaro 在其掌握的信息与 Aoi 发送的字符串下寻找最短路径的策略。 ### 实现细节 你需要提交 $2$ 个文件。 第一个文件为 `Aoi.cpp`。该文件用于实现 Aoi 的策略,并应实现以下函数。程序需通过预处理指令 `#include` 包含 `Aoi.h`。 * `std::string aoi(int N, int M, int Q, int K, std::vector A, std::vector B, std::vector C, std::vector T, std::vector X)` 此函数在每个测试用例中只被调用一次。 * 参数 $N$ 是 IOI 国 中的城市数量。 * 参数 $M$ 是 IOI 国 中的道路数量。 * 参数 $Q$ 是调查计划的数量。 * 参数 $K$ 是 Bitaro 遗失长度信息的道路条数。 * 参数 $A, B, C$ 为长度为 $M$ 的数组。表示第 $i$ 条道路($0 \le i \le M-1$)双向连接城市 $A[i]$ 与城市 $B[i]$,长度为 $C[i]$。 * 参数 $T$ 为长度为 $Q$ 的数组。表示第 $j$ 个计划($0 \le j \le Q-1$)要调查的城市为 $T[j]$。 * 参数 $X$ 为长度为 $K$ 的数组。表示 Bitaro 遗失长度信息的道路为 $X[0], X[1], \dots, X[K-1]$。 * 返回值为 Aoi 向 Bitaro 发送的字符串 $s$。 * 字符串 $s$ 的每个字符必须是 ‘0’ 或 ‘1’。若不满足此条件,你的程序将被判定为 **Wrong Answer [1]**。 * 字符串 $s$ 的长度最多为 $12000$。若不满足此条件,你的程序将被判定为 **Wrong Answer [2]**。 第二个文件为 `Bitaro.cpp`。该文件用于实现 Bitaro 的策略,并应实现以下函数。程序需通过预处理指令 `#include` 包含 `Bitaro.h`。 * `void bitaro(int N, int M, int Q, int K, std::vector A, std::vector B, std::vector C, std::vector T, std::vector X, std::string s)` 此函数会在 `aoi` 函数被调用之后且仅被调用一次。 * 参数 $N$ 是 IOI 国 中的城市数量。 * 参数 $M$ 是 IOI 国 中的道路数量。 * 参数 $Q$ 是调查计划的数量。 * 参数 $K$ 是 Bitaro 遗失长度信息的道路条数。 * 参数 $A, B, C$ 为长度为 $M$ 的数组。表示第 $i$ 条道路($0 \le i \le M-1$)双向连接城市 $A[i]$ 与城市 $B[i]$,长度为 $C[i]$。 * 参数 $T$ 为长度为 $Q$ 的数组。表示第 $j$ 个计划($0 \le j \le Q-1$)要调查的城市为 $T[j]$。 * 参数 $X$ 为长度为 $K$ 的数组。表示 Bitaro 遗失长度信息的道路为 $X[0], X[1], \dots, X[K-1]$。 * 参数 $s$ 是一个每个字符均为 ‘0’ 或 ‘1’ 的字符串,表示 Aoi 发送给 Bitaro 的字符串。 在 `Bitaro.cpp` 中,你的程序可以调用如下函数。 ```cpp void answer(const std::vector &e) ``` * 在第 $(j+1)$ 次调用($0 \le j \le Q-1$)该函数时,你需要回答从城市 $0$ 到第 $j$ 个调查计划目标城市 $T_j$ 的最短路径。 * 参数 `e` 是一个数组,表示从城市 $0$ 到城市 $T_j$ 的最短路径所经过的道路序列。 * 设数组 `e` 的长度为 $n$。元素 `e[0], e[1], \ldots, e[n-1]` 是该最短路径上按行进顺序经过的道路的编号。 * 若存在多条最短路径,任选其一作为答案即可。 * 参数 `e` 的每个元素必须在 $0$ 到 $M-1$ 之间。若不满足此条件,你的程序将被判定为 **Wrong Answer [3]**。 * 参数 `e` 所指示的道路序列必须构成一条从城市 $0$ 到城市 $T_j$ 的路径。更正式地,它必须满足以下条件。 * 存在一列数字 $u_0, u_1, \ldots, u_n$ 使得 * $u_0 = 0$。 * $u_n = T_j$。 * 道路 $e[k]$($0 \le k \le n-1$)连接城市 $u_k$ 与城市 $u_{k+1}$。 * 若不满足这些条件,你的程序将被判定为 **Wrong Answer [4]**。 * 若参数 `e` 指示的道路序列并非所有从城市 $0$ 到城市 $T_j$ 的路径中长度最短的一条,你的程序将被判定为 **Wrong Answer [5]**。这里,路径长度定义为所用道路长度之和。 * 函数 `answer` 必须被调用恰好 $Q$ 次。若在 `bitaro` 函数结束时,对 `answer` 的调用次数不等于 $Q$,你的程序将被判定为 **Wrong Answer [6]**。 ### 重要注意事项 * 你的程序可以为内部使用实现其他函数,或使用全局变量。提交的文件将与评测程序一起编译,形成单个可执行文件。所有全局变量与内部函数应声明在未命名命名空间中,以避免与其他文件冲突。评测时会分别以 Aoi 进程与 Bitaro 进程运行。Aoi 进程与 Bitaro 进程不能共享全局变量。 * 你的程序不得使用标准输入与标准输出。你的程序不得以任何方式与其他文件通信。但你可以向标准错误输出调试信息。 ### 编译与测试运行 你可以从比赛网页下载包含样例评测器的压缩包,用于本地测试。压缩包中也包含你程序的样例源文件。 样例评测器文件为 `grader.cpp`。为测试你的程序,请将 `grader.cpp`、`Aoi.cpp`、`Bitaro.cpp`、`Aoi.h`、`Bitaro.h` 放在同一目录下,并运行以下命令进行编译。你也可以运行压缩包内的 `compile.sh`。 ```bash g++ -std=gnu++20 -O2 -o grader grader.cpp Aoi.cpp Bitaro.cpp ``` 当编译成功时,将生成可执行文件 `grader`。 注意,实际评测器不同于样例评测器。样例评测器作为单进程执行,从标准输入读取数据,并向标准输出与标准错误输出写出结果。

输入格式

样例评测器从标准输入读取如下数据。 > $N$ $M$\ > $A_0$ $B_0$ $C_0$\ > $A_1$ $B_1$ $C_1$\ > $A_{M-1}$ $B_{M-1}$ $C_{M-1}$\ > $Q$\ > $T_0$ $T_1$ $\cdots$ $T_{Q-1}$\ > $K$\ > $X_0$ $X_1$ $\cdots$ $X_{K-1}$

输出格式

样例评测器向标准输出与标准错误输出输出如下信息(引号仅为说明)。 * 若你的程序被判为 **Wrong Answer [1], [2], [3], [4], 或 [6]**,样例评测器会在标准错误输出写出其类型,如 “Wrong Answer [1]”。标准输出不会输出任何内容。 * 否则,`aoi` 函数返回的字符串 $s$ 的长度会以 “Accepted: 2024” 的格式输出到标准错误输出。此外,在第 $(j+1)$ 次($0 \le j \le Q-1$)对 `answer` 的调用中,路径长度会输出到标准输出的第 $(j+1)$ 行。样例评测程序 **不会检查** 该路径是否最短。 若你的程序同时满足多种 Wrong Answer 的条件,样例评测器仅报告其中一种。

说明/提示

### 示例通信 下面给出一个样例评测器的输入及相应的函数调用。 | 样例输入 1 | 调用 | 返回值 | |---|---|---| | $$\texttt{3 3}\\ \texttt{1 2 1} \\ \texttt{0 2 2} \\ \texttt{0 1 3} \\ \texttt{2} \\ \texttt{2 1} \\ \texttt{2} \\ \texttt{0 1}$$ | `aoi(3, 3, 2, 2, [1, 0, 0], [2, 2, 1], [1, 2, 3], [2, 1], [0, 1])` | | | ^ | | `"101001"` | | ^ | `bitaro(3, 3, 2, 2, [1, 0, 0], [2, 2, 1], [-1, -1, 3], [2, 1], [0, 1], "101001")` | | | ^ | `answer([1])` | | | ^ | `answer([1, 0])` | | 从城市 $0$ 到城市 $1$ 的最短路径,可以按顺序经过道路 $1$ 和 $0$,或者仅经过道路 $2$。因此,在本样例的第二次对 `answer` 的调用中,调用 `answer([2])` 也是可以接受的。 从比赛网站下载的文件 `sample-01-in.txt` 与输入样例 $1$ 相对应。压缩包中的 `sample-01-in.txt` 与 `sample-02-in.txt` 可作为样例评测器的输入。 ### 约束 所有输入数据均满足以下条件: * $2 \le N \le 10000$。 * $1 \le M \le 20000$。 * $1 \le Q \le 16$。 * $1 \le K \le 300$。 * $0 \le A_i < B_i \le N-1$($0 \le i \le M-1$)。 * $(A_i, B_i) \ne (A_j, B_j)$($0 \le i < j \le M-1$)。 * $1 \le C_i \le 10^{12}$($0 \le i \le M-1$)。 * $1 \le T_j \le N-1$($0 \le j \le Q-1$)。 * $T_j \ne T_k$($0 \le j < k \le Q-1$)。 * $0 \le X_k \le M-1$($0 \le k \le K-1$)。 * $X_k \ne X_l$($0 \le k < l \le K-1$)。 * 通过若干条道路可以在任意两座城市之间往来。 * 所有输入值均为整数。 ### 评分 若你的程序在任意测试用例中被判定为 **Wrong Answer [1] - [6]**(见实现细节)或出现任意类型的运行时错误(TLE、MLE、异常结束等),你的得分为 $0$ 分。 否则,评分依据为在本题所有测试用例中,函数 `aoi` 返回的字符串 $s$ 的最大长度 $L$。 * 若 $1561 \le L \le 12000$,得分为 $\left\lfloor \dfrac{100\,000}{L-560} \right\rfloor$。 * 若 $0 \le L \le 1560$,得分为 $100$ 分。 其中,$\lfloor x \rfloor$ 表示不超过 $x$ 的最大整数。