Public Judge

pjudge

Time Limit: 3 s Memory Limit: 2048 MB Total points: 100
[+7]
Statistics

你知道:

  1. 所谓一棵 TrieT 是一棵有根树,每条边上写有一个字符。对于 Trie 中的任意顶点 xx 的两个子节点 yz 不应有相同字符写在边 (x,y)(x,z) 上。
  2. 假设有一棵以 r 为根的 Trie 树 T。对于一个节点 xx 表示的字符串是从根 rx 的路径上各边字符按顺序连接起来的结果字符串。特别地,由根 r 表示的字符串是空字符串。可以证明,不同顶点表示的字符串总是不同的。
  3. 如果字符串 S 存在于 Trie T 中,当且仅当存在一个顶点 x,由 x 表示的字符串是 S
  4. 失配树 F 是给定 Trie 树 T 的一棵有根树,根与 T 的根相同,记为 r。定义节点 x 表示的字符串为 Sx。对于非根节点 x,设 USx 的最长真后缀(真后缀指 S 的一个后缀,且不等于 S),且 U 存在于 T 中。那么,failx 定义为满足 Sfailx=UT 中顶点。注意,Sx 的空后缀总存在于 T 中,因此 failx 一定存在。失配树 F 的边集为 {(x,failx)x[1,n],xr}。可以证明这些边构成一棵树。

现在你有一棵包含 n 个顶点的 Trie 树 T,编号为 1n。它的根未知。字符集为 [1,n] 中的所有整数。

你构造了对应的失配树 F,然后将 T 的边(从根向外的方向)与 F 的边(指向根的方向)组合,生成了一个 有向图 G,包含 n 个节点和 2n2 条有向边。具体构造如下:

  1. 对于每个非根顶点 uG 包含一条边 fauu,其中 fauuT 中的父节点。
  2. 对于每个非根顶点 uG 包含一条边 ufailu

给定包含 n 个顶点的有向图 G(边按任意顺序给出),你需要:

  1. 找到 T 的根顶点 r
  2. 确定 G 的哪些边属于 T,哪些边属于 F
  3. 找到一种合法的方式为 T 的每条边标注一个字符(字符为 [1,n] 中的整数),使得 T 和对应的失配树 F 符合 G

输入格式:

每个测试点中包含多组测试数据。

输入的第一行包含整数 T,表示数据组数。对于每组数据:

输入的第一行包含一个整数 n,表示图 G 的节点数。

接下来 2n2 行,每行包含两个整数 x,y ,表示 G 中从 xy 的一条边。

输出格式:

对于每组测试数据:

  • 如果无法找到合法方案,输出一行 No
  • 否则,输出一行 Yes,接着输出 n1 行,每行包含三个整数 x,y,z (1x,y,zn),表示 T 中一条从 xy 的边(xy 的父节点),且该边标注的字符为 z。输出的边应满足输出的树是 T,并且 T 和对应的失配树与 G 相符。

如果有多种合法方案,你可以输出任意一种。

样例输入 1

4
4
1 4
4 1
1 2
2 1
2 3
3 4
2
1 2
1 2
1
3
1 2
2 1
2 3
3 2

样例输出 1

Yes
1 2 1
2 3 2
4 1 1
No
Yes
Yes
1 2 1
2 3 1

子任务

对于所有数据,1x,yn1n105n5×105

子任务一(8 分)

n50

子任务二(10 分)

n300

子任务三(9 分)

n2000

子任务四(26 分)

保证对于所有数据,存在至少一组以 1 号点为根的合法的解。

子任务五(47 分)

没有额外的限制。