Graph Compression
题号:NC13818
时间限制:C/C++/Rust/Pascal 2秒,其他语言4秒
空间限制:C/C++/Rust/Pascal 256 M,其他语言512 M
64bit IO Format: %lld

题目描述

众所周知,给定n个点m条边的有向图,这里认为点从0到n-1标号,如果采用邻接链表的方式存储,也就是对每个点u拉出一条链表来记录所有满足存在u->v的有向边的点v,那么总共需要m个链表节点(让我们忘掉头结点的悲伤)。

(该图引自"Introduction to Algorithms, 3rd Edition")
小Q同学偶然间得知了一种压缩算法,可以有效的减少链表节点个数,具体来说,就是每个链表节点记录一个二元组(offset,bitmask),这里bitmask是一个w位无符号整数,通常来说w=32或者64,并且offset是w的非负整数倍,那么如果点u拉出的链表中某个节点的bitmask的第k位是1,则说明存在u -> offset+k的有向边。

但是这个算法在某些情况下并不能很有效的压缩原图,比如存在点0到点1,w+1,2w+1,3w+1,...的有向边时,从点0拉出的链表节点个数并没有减少。为了应对这种情况,一个解决办法是对原图重标号,也就是构造一个0,1,2,...,n-1的排列p,使得原图的点i对应新图中的点p_i,然后再对新图进行压缩。

小Q同学想知道有多少种重标号的方案能够最小化存储压缩后的图所需要的链表节点个数,由于这个问题在w ≥ 3的情况下相当困难,你只需要帮小Q同学解决w=2的情况即可。

输入描述:

第一行是一个正整数T(≤ 10),表示测试数据的组数, 对于每组测试数据, 第一行是一个整数n(1 ≤ n ≤ 20),表示有向图的顶点数, 接下来是一个n行n列的01矩阵,矩阵的第i行第j列为1表示有一条从i号点连向j号点的有向边,为0则表示没有。

输出描述:

对于每组测试数据,输出两个整数,表示存储压缩后的图所需要的最少链表节点数,以及对应的重标号方案数。
示例1

输入

复制
2
2
0 1
0 0
3
0 1 0
1 0 1
0 1 0

输出

复制
1 2
3 2