题目大意
有
n个结点,编号
1到
n。可以在当中连边,点
i,j之间可以连
ci,j种颜色的边,且每对点之间最多连一条边。求使得整个图连通的连边方案数(边的颜色不同算作不同方案)。答案模
1000000007。
8⩽n⩽16,
n∈Z。
思路
设
f[s]表示将集合
s中的点连边,使得这些点连通的方案数。容易想到把集合
s分成两个小集合
s1,s2,用两个小的状态更新当前状态。然而这样有几个问题:
- 两个小集合内的点不一定是连通的。
- 同一种方案可能有多种划分的方式,方案会算重。
- 状态转移需要在这两个小集合之间连边,连边的方案数很难处理。
正难则反,设
g[s]表示将集合
s中的点连边,使得这些点不连通的方案数,
h[s]表示任意连边的方案数,则有
f[s]=h[s]−g[s]。由于每条边都有
ci,j+1种选择(连
ci,j种颜色的边以及不连边),可以得到
h[s]的表达式:
h[s]=i,j∈s∏(c[i][j]+1)
下面要求
g[s],容易想到把集合
s分成两个小集合
s1,s2,用两个小的状态更新当前状态。然而这样有几个问题:
- 两个小集合内的点不一定是不连通的。
- 同一种方案可能有多种划分的方式,方案会算重。
这个时候就不能正难则反了,要敢于直面惨淡的人生。
既然
s中的点不连通,那么一定可以从其中选出一个连通的部分出来(设为
s1),而另一部分连不连通不重要,因为这两部分中间没有连边,整个图一定是不连通的。可以初步写出递推式:
g[s]=s1∪s2=s∑f[s1]⋅h[s2]
但是方案数依然会算重,因为同一种方案中有多个连通块可以当做
s1。解决方法很简单,在集合
s中任选一个点
k,枚举
s1的时候保证
k∈s1,就不会多解;
s1的大小是任意的,所以也不会漏解。