NEERC 曾推出过一系列关于仙人掌图(cactus)的问题——仙人掌图是一种连通的无向图,其中每条边最多属于一个简单环。直观地说,仙人掌图是树的一种推广,允许存在一些环。
在 2005 年,第一道关于仙人掌图的题目被简单地命名为“Cactus”。2007 年是“Cactus Reloaded”,2010 年是“Cactus Revolution”,2013 年是“Cactus Automorphisms”。以下是这些题目中使用过的一个仙人掌图示例:
四年来,评测人员不得不为拥有数千个顶点的仙人掌图生成测试文件。当然,人们构建了许多复杂度不断增加的测试生成器,最终形成了一种特定领域的语言,称为 CGL(Cactus Generator Language,仙人掌生成语言)。CGL 可以紧凑地定义一个大型仙人掌图用于测试。在本题中,你需要解析该语言的一个简化版本,我们称之为 SCGL(Simple Cactus Generator Language,简单仙人掌生成语言),并输出生成的仙人掌图。
仙人掌图的输出方式是列出覆盖整个图的最小边不相交路径集。SCGL 仙人掌定义的语法由以下使用扩展巴科斯范式(EBNF)给出的 graph 非终结符表示:
graph = "c"
| "c(" list ")"
| "loop(" list ")"
| "t(" list ")"
list = graph { "," graph }
| (number | range | variable ) ["," graph ]
number = nzdig { "0" | nzdig }
nzdig = "1" | "2" | ... | "8" | "9"
range = "range(" variable "," numvar "," numvar ")"
variable = "A" | "B" | ... | "Y" | "Z"
numvar = number | variable一个 graph 生成规则表示一个具有两个标记顶点的图——第一个顶点(first)和最后一个顶点(last)。图定义规则具有以下语义:
- 基本构建块
c表示一个仅有两个顶点(一个是第一个,另一个是最后一个)和一条边的图。 c(σ)规则将指定的图列表σ从左到右连接成一条链,将列表中第一个图的最后一个顶点与第二个图的第一个顶点合并,将第二个图的最后一个顶点与第三个图的第一个顶点合并,依此类推。结果图的第一个顶点是列表中第一个图的第一个顶点,结果图的最后一个顶点是列表中最后一个图的最后一个顶点。loop(σ)规则将指定的图列表σ从左到右连接,将列表中第一个图的最后一个顶点与第二个图的第一个顶点合并,依此类推,类似于c(σ),同时将列表中最后一个图的最后一个顶点与列表中第一个图的第一个顶点合并以形成一个环。结果图的第一个和最后一个顶点分别是列表中第一个图的第一个和最后一个顶点。loop只能应用于包含多于一个图的列表。t(σ)规则连接指定的图列表σ,合并它们的所有第一个顶点。结果图的第一个和最后一个顶点分别是列表中第一个图的第一个和最后一个顶点。
图的 list 可以显式指定(通过逗号分隔的列表),也可以使用列表重复(list repetition)来指定,即使用一个 number、range 或 variable,后面可选地跟一个逗号和一个图。当列表重复中未显式指定图时,则假定给定的图为 c。
最简单的列表重复是使用 number 非终结符定义的。它表示一个包含指定整数个给定图副本的列表。
范围列表重复由 range(ν, α, β) 规则定义,它有三个组成部分——一个变量 ν,以及数字 α 和 β。如果字符序列 ξ 是一个图,则 c|loop|t(range(ν, α, β), ξ) 被称为范围启用规则(range-enabled rules),变量 ν 被称为 ξ 中的绑定变量。在范围启用规则的上下文中,ξ 被重复 $|β - α| + 1$ 次以形成一个列表。ξ 中出现的每个变量 ν 都会被 α 和 β 之间(包含边界)的连续整数按升序替换。这产生了一个包含 $|β - α| + 1$ 个图的列表,然后根据相应范围启用规则的规范将它们连接起来。α 和 β 本身可能引用在外部范围启用规则中绑定的变量。
在一个良构(well-formed)的图中:
每个 variable 非终结符(从 A 到 Z 的字母)在 range(ν, α, β) 规则中作为 ν 最多出现一次;
语法允许的所有其他 variable 非终结符的出现都是已绑定的。
注意,如果字符序列 ξ 是一个图,则 ξ、c(ξ)、c(1, ξ)、t(ξ) 和 t(1, ξ) 都表示同一个图。另一方面,loop(ξ) 和 loop(1, ξ) 都是不允许的。
以下示例说明了这些基本规则。图的第一个和最后一个顶点分别用字母 F 和 L 标记。
输入格式
输入文件包含一行良构的 SCGL 仙人掌定义。虽然 SCGL 的语法和语义本身不能保证生成的图一定是仙人掌图,但本题的输入文件总是定义一个仙人掌图——每条边最多属于一个简单环,且顶点之间没有多重边。例如,loop(3,loop(3)) 和 loop(2) 都是不可能的。
输入文件中的行长度最多为 1000 个字符,定义的仙人掌图最多有 50 000 个顶点。由 number 非终结符表示的整数不超过 50 000。
输出格式
输出文件的第一行必须包含两个整数 $n$ 和 $m$。其中 $n$ 是图中的顶点数。顶点编号从 1 到 $n$,其中 1 是图中第一个顶点的编号,$n$ 是图中最后一个顶点的编号。其他顶点可以任意编号。图的边由一组边不相交的路径表示,其中 $m$ 是此类路径的最小数量。
接下来的 $m$ 行,每行必须包含图中的一条路径。路径以一个整数 $k_i$ ($k_i \ge 2$) 开头,后跟 $k_i$ 个从 1 到 $n$ 的整数。这些 $k_i$ 个整数表示路径上的顶点。路径可以多次经过同一个顶点,但整个输出文件中的每条边必须被遍历且仅被遍历一次。
样例
样例输入 1
c(c,t(loop(3),c(c,loop(6))),loop(c,c,t(c,loop(4))))
样例输出 1
15 1 19 1 2 9 10 11 12 13 10 15 9 14 2 3 4 5 6 7 8 3
样例输入 2
c
样例输出 2
2 1 2 1 2
样例输入 3
c(2)
样例输出 3
3 1 3 1 2 3
样例输入 4
c(3)
样例输出 4
4 1 4 1 2 3 4
样例输入 5
t(c(3),c,c)
样例输出 5
6 2 2 1 2 5 3 1 4 5 6
样例输入 6
c(2,t(c(2),c,c))
样例输出 6
9 3 3 2 1 3 3 4 5 6 5 1 7 5 8 9