【题目】BZOJ-2560 串珠子

题目大意

n n 个结点,编号 1 1 n n 。可以在当中连边,点 i , j i,j 之间可以连 c i , j c_{i,j} 种颜色的边,且每对点之间最多连一条边。求使得整个图连通的连边方案数(边的颜色不同算作不同方案)。答案模 1000000007 1000000007

8 n 16 8\leqslant n\leqslant 16 n Z n\in Z


思路

f [ s ] f[s] 表示将集合 s s 中的点连边,使得这些点连通的方案数。容易想到把集合 s s 分成两个小集合 s 1 , s 2 s_1,s_2 ,用两个小的状态更新当前状态。然而这样有几个问题:

  1. 两个小集合内的点不一定是连通的。
  2. 同一种方案可能有多种划分的方式,方案会算重。
  3. 状态转移需要在这两个小集合之间连边,连边的方案数很难处理。

正难则反,设 g [ s ] g[s] 表示将集合 s s 中的点连边,使得这些点不连通的方案数, h [ s ] h[s] 表示任意连边的方案数,则有 f [ s ] = h [ s ] g [ s ] f[s]=h[s]-g[s] 。由于每条边都有 c i , j + 1 c_{i,j}+1 种选择(连 c i , j c_{i,j} 种颜色的边以及不连边),可以得到 h [ s ] h[s] 的表达式:

h [ s ] = i , j s ( c [ i ] [ j ] + 1 ) h[s]=\prod_{i,j\in s}(c[i][j]+1)

下面要求 g [ s ] g[s] ,容易想到把集合 s s 分成两个小集合 s 1 , s 2 s_1,s_2 ,用两个小的状态更新当前状态。然而这样有几个问题:

  1. 两个小集合内的点不一定是不连通的。
  2. 同一种方案可能有多种划分的方式,方案会算重。

这个时候就不能正难则反了,要敢于直面惨淡的人生
既然 s s 中的点不连通,那么一定可以从其中选出一个连通的部分出来(设为 s 1 s_1 ),而另一部分连不连通不重要,因为这两部分中间没有连边,整个图一定是不连通的。可以初步写出递推式:

g [ s ] = s 1 s 2 = s f [ s 1 ] h [ s 2 ] g[s]=\sum_{s_1\cup s_2=s}f[s_1]\cdot h[s_2]

但是方案数依然会算重,因为同一种方案中有多个连通块可以当做 s 1 s_1 。解决方法很简单,在集合 s s 中任选一个点 k k ,枚举 s 1 s_1 的时候保证 k s 1 k\in s_1 ,就不会多解; s 1 s_1 的大小是任意的,所以也不会漏解。

发布了26 篇原创文章 · 获赞 13 · 访问量 4880

猜你喜欢

转载自blog.csdn.net/PHenning/article/details/100148426