P13150 [GCJ 2018 #3] Name-Preserving Network

题目描述

一个研究联盟正在建设一个新的数据中心。在数据中心中,一组计算机被设置为协同工作,并通过网络进行通信。该网络仅通过计算机之间的直接双向连接工作。对于没有直接连接的两台计算机 $c_1$ 和 $c_2$,只要存在一条由连接 $l_1, l_2, ..., l_k$ 组成的路径,使得每对相邻连接 $l_i$ 和 $l_{i+1}$ 共享一个端点,且 $c_1$ 是 $l_1$ 的一个端点,$c_2$ 是 $l_k$ 的一个端点,那么 $c_1$ 和 $c_2$ 依然可以通信。任意两台计算机之间最多只能有一条直接连接。 联盟要求你提交一个网络设计,说明网络中有多少台计算机,以及它们之间如何连接。你提交的每个网络设计都必须满足以下特定限制: 1. 网络中的计算机数量必须在 $L$ 到 $U$ 之间(包含两端)。 2. 每台计算机必须正好作为 4 条连接的端点,即与 4 台不同的计算机直接相连。 3. 任意两台计算机都必须能够互相通信,如上所述。 4. 即使系统关闭时计算机的编号被随机更改,计算机也必须能够唯一地识别自己。 对于最后一点,具体说明如下:在你的网络设计中,每台计算机最初被分配一个唯一的整数编号,范围为 $1$ 到 $N$。然而,系统在某次关闭后,重新启动时这些编号可能会被重新排列——也就是说,每台计算机仍然拥有 $1$ 到 $N$ 之间的唯一编号,但不一定是原来的编号。网络必须能够仅凭现有的直接连接关系,恢复出原始的编号分配。 为了评估你的网络设计,研究联盟设置了一个自动化程序。该程序会接收你的网络设计,验证上述第 1-3 条限制,然后返回一个经过如下更改的网络设计副本: - 唯一编号被随机重新排列(即每个编号现在在任意计算机上都是等可能的); - 每条连接按照较小编号在前的顺序输出(使用新的编号); - 所有连接按照第一个端点编号递增排序,若相同则按第二个端点递增排序(即字典序)。 你需要能够准确判断编号是如何被更改的。形式化地说,自动化程序会生成一个 $1$ 到 $N$ 的随机排列 $f$,并将这些编号分配给一个“空白副本”网络(所有原有连接已移除)。然后,对于你设计中的每一条连接 $i$ 和 $j$,在副本中添加一条 $f(i)$ 和 $f(j)$ 之间的连接。你必须准确还原出 $f$。如果存在另一个不同的排列 $f'$ 也能得到相同的连接集合,而你返回了 $f'$,联盟将不接受你的设计,因为此时无法确保恢复的编号就是原始编号。 对于每个 $N$,其中 $10 \leq N \leq 100$,都至少存在一个满足所有上述限制且具有如下性质的网络:对其应用任意两个不同的排列 $f$ 和 $f'$,会得到不同的连接集合。 ### 交互协议 本题为交互题,这意味着输入输出方式与标准题目不同。你需要与一个独立的进程进行交互,该进程既为你提供信息,也评估你的回答。所有信息通过标准输入传入你的程序;你需要输出的内容通过标准输出发送。请注意,许多编程语言默认会缓冲输出,因此在等待输入前请确保输出已刷新(例如,使用 flush)。详见 FAQ 关于 flush 的说明。你通过标准错误输出的内容会被忽略,但可能会占用内存并计入内存限制,因此请勿输出过多内容。为方便调试,题目末尾提供了本地测试工具脚本(Python)。此外,分析部分还提供了以往 Code Jam 交互题的参考实现。 最初,你的程序应读取一行,包含一个整数 $T$,表示测试用例数量。然后,你需要处理 $T$ 个测试用例。 对于每个测试用例,你的程序首先读取一行,包含两个整数 $L$ 和 $U$,表示网络中计算机数量的取值范围(包含两端)。 接下来,你需要设计一个包含 $N$ 台计算机的网络,并输出 $2N+1$ 行,描述该网络设计。第一行包含一个整数 $N$。接下来的 $2N$ 行,每行包含两个整数 $A$ 和 $B$,表示一条连接 $A$ 和 $B$ 的不同计算机,且 $A \neq B$。注意,如果你输出了 $A$ $B$,则不能再输出 $A$ $B$ 或 $B$ $A$。 评测程序收到你的网络设计后,会首先检查前 3 条限制。如果有任何一条不满足,评测程序会返回一行 $-1$,然后结束所有通信并等待你的程序结束。如果你的程序正常结束且未违反其他限制,将收到 Wrong Answer 判定。 如果所有限制均满足,评测程序会返回 $2N+1$ 行。第一行包含整数 $N$(与你输出的 $N$ 相同)。接下来的 $2N$ 行,每行包含两个整数,描述副本网络的连接,格式同上。副本的生成方式如前所述,排列 $f$ 是从所有可能的排列中等概率随机选取的,且与网络设计无关。 完成一个测试用例后,你需要输出一行,包含 $N$ 个整数 $X_1, X_2, ..., X_N$,表示你设计中编号为 $i$ 的计算机在副本中被分配到的编号 $X_i$。 如果该列表不是评测程序生成的排列,将收到 Wrong Answer 判定。如果这是最后一个测试用例,评测程序不会再发送任何信息。否则,评测程序会发送一行 $-1$,然后不再通信。在这两种情况下,评测程序都会等待你的程序结束,只有在程序正常结束且未违反资源限制时才会判定为 Wrong Answer。 请勿在所有测试用例结束后继续向评测程序输出内容。也就是说,在输出最后一个测试用例的 $X$ 列表后,不要再输出任何内容,否则会收到 Wrong Answer 判定。 注意,你可以为不同测试用例提交相同的网络设计,只要该设计同时满足所有相关限制。此外,评测程序的随机种子是固定的,因此以相同顺序提交相同的原始网络设计,会得到相同的副本。

输入格式

见交互协议。

输出格式

见交互协议。

说明/提示

**样例交互** 注意,此样例交互使用的 $L$ 值比实际数据小,仅为说明方便。此外,正如题目所述,$N=6$ 时不存在满足“对任意不同排列 $f$ 和 $f'$,应用后得到的连接集合不同”这一性质的网络,因此即使题目限制允许,设计 $N=6$ 的网络也是不明智的! ``` t = readline_int() // 读取 t=2 limits = readline_int_list() // 读取 6 50 printline 6 to stdout // 使用 6 台计算机。选手设计了一个八面体网络 printline 2 4 to stdout printline 1 2 to stdout // 连接的输出顺序不限 printline 3 1 to stdout // 端点顺序也不限 printline 1 4 to stdout printline 1 5 to stdout printline 2 3 to stdout printline 2 6 to stdout printline 3 5 to stdout printline 3 6 to stdout printline 4 5 to stdout printline 4 6 to stdout printline 5 6 to stdout flush stdout // 评测程序验证网络是否满足前 3 条限制,并随机选择 2 6 3 1 5 4 作为新排列 n = readline_int() // 读取 n=6 repeat 12 times: add readline_int_list() to edges // 读取 1 2, 1 4, 1 5, 1 6, 2 3, 2 5, // 2 6, 3 4, 3 5, 3 6, 4 5, 4 6, 按顺序 printline 2 5 6 1 3 4 // 这与评测程序返回的内容一致,但不是评测程序实际用的排列 flush stdout // 评测程序判定错误 limits = readline_int_list() // 期望读取下一个用例,但收到 -1,表示答案错误 exit // 退出,避免歧义性 TLE ``` 你可以使用本地测试工具进行本地或平台测试。要在本地测试,需要并行运行该工具和你的代码;可以使用我们的 [interactive runner](https://storage.googleapis.com/coding-competitions.appspot.com/interactive_runner.py)。更多信息请阅读该文件中的注释说明。 测试工具的使用说明已包含在工具注释中。建议你自行添加测试用例。请注意,虽然测试工具旨在模拟评测系统,但它**不是**真实的评测系统,可能存在差异。 **限制条件** - $1 \leq T \leq 30$。 **测试点 1(9 分,可见)** - $L = 10$。 - $U = 50$。 **测试点 2(16 分,隐藏)** - $10 \leq L \leq 50$。 - $L = U$。 由 ChatGPT 4.1 翻译