#loj5691. 「PA 2026」Kod Prüfera
「PA 2026」Kod Prüfera
[AdditionalFile5691.zip](file://AdditionalFile5691.zip?type=additional_file)
#5691. 「PA 2026」Kod Prüfera
标签: 传统 | 时间限制: 25000 ms | 内存限制: 1024 MiB |
题目描述
题目译自 PA 2026 Runda 5 Kod Prüfera
对于一棵拥有 个顶点的树(其中 ),顶点编号从 到 ,其 Prüfer 编码是一个唯一确定的长度为 的数字序列,可以通过以下简单算法获得:
当树有超过两个顶点时:
找到编号最小的度为 1 的顶点
将该顶点的唯一邻居的编号加入编码
从树中移除该顶点
可以证明,任何由 到 之间的数字组成的长度为 的序列都是某棵树的 Prüfer 编码,且 Prüfer 编码唯一确定了其对应的树。关于 Prüfer 编码的这些事实以及其他有趣的结论,可以在维基百科等资料中找到。
在本题中,我们给定了一棵树,并考虑通过不同方式给树的顶点编号所生成的 Prüfer 编码。如果 是一种顶点编号方式(形式上,是从顶点集合到集合 的双射函数),我们用 表示具有此编号方式的树的 Prüfer 编码。
你的任务是确定给定树的字典序最小的 Prüfer 编码,即对于某种编号方式 ,序列 是所有可能编号方式 中字典序最小的。这意味着对于任意其他编号方式 ,要么 ,要么在 和 第一个不同的位置上, 中的数字小于 中的数字。
你需要为 个独立的测试用例解决此问题。
输入格式
第一行输入包含一个整数 ,表示测试用例的数量。
每个测试用例的描述以一行开始,包含一个整数 ,表示树的顶点数。顶点编号从 到 ,但这并不一定对应于字典序最小的 Prüfer 编码。
接下来的 行描述了树的边。每行包含两个整数 和 ,表示顶点 和 之间有一条边。
所有测试用例中 的总和不超过 。
输出格式
输出 行,每个测试用例一行。在第 行,输出 个数字组成的序列,即第 个测试用例中树的最佳顶点编号所对应的字典序最小的 Prüfer 编码。
样例
输入
2
5
1 2
2 3
3 4
3 5
16
8 1
9 1
10 1
11 2
12 2
2 3
13 4
4 3
14 5
15 5
5 3
3 1
1 6
6 7
7 16
输出
1 1 2
1 1 1 2 2 3 4 3 5 5 3 1 6 7
在第一个测试用例中,使得 Prüfer 编码字典序最小的顶点编号方案示例为:。
对于这种编号,Prüfer 编码生成算法在第一步中将选择编号为 的顶点(并将该顶点唯一邻居的编号 加入编码)。在第二步中,将选择编号为 的顶点(其唯一邻居也是 )。在第三步中(移除顶点 和 后),顶点 已经成为叶子节点,将被选中,作为编码的最后一个元素,添加其邻居的编号 。
在第二个测试用例中,最优策略是不对顶点进行重新编号,且输入中边的顺序正好对应了 Prüfer 编码算法中删除叶子节点的顺序。