给你 n n n 个点,起点为 1 1 1,终点为 n n n,让你求满足下列条件的无向图的数量:
答案模 m m m 输出。
我们假设 d i d_i di 表示点 i i i 到起点的最短距离。
我们可以发现,如果要把点 i i i 和点 j j j (假设 d i ≤ d j d_i \leq d_j di≤dj)有边, 那就必须满足 d j − d i ≤ 1 d_j - d_i \leq 1 dj−di≤1 。
于是我们考虑对于 d i d_i di 来分层图 D P DP DP 。
我们设 f i , j f_{i,j} fi,j 表示已经用了 i i i 个点,最后一层有 j j j 个点的方案数(因为 d i d_i di 的准确数值并不重要,重要的是是否满足条件,所以并不用记录)。
考虑怎么转移。
我们设上一层的点数为 l l l 。
因为是分层图,所以该层的点只能连向上一层的点,每个点至少要连一条边,并且这种连边没有任何限制,所以这种连边方式一共有 ( 2 l − 1 ) j (2^l - 1)^j (2l−1)j 种方案。
又因为该层的点可以互相连边,所以这种连边的方式有 2 j ∗ ( j − 1 ) / 2 2^{j*(j-1)/2} 2j∗(j−1)/2 种方案。
又因为每一层的点无法固定,所以我们是从能选的点中选 j j j 个点,选点一共有 ( n − i + j j ) \binom{n - i + j}{j} (jn−i+j)种方案。
于是我们可以得到转移方程:
f i , j = f i , j + f i − j , l ∗ ( n − i + j j ) ∗ 2 j ∗ ( j − 1 ) / 2 ∗ ( 2 l − 1 ) j f_{i,j} = f_{i,j} + f_{i - j, l} * \binom{n - i + j}{j}*2^{j*(j-1)/2}*(2^l - 1)^j fi,j=fi,j+fi−j,l∗(jn−i+j)∗2j∗(j−1)/2∗(2l−1)j
其中 i , j , l i,j,l i,j,l 是要枚举的,于是时间复杂度就是 O ( n 3 ) O(n^3) O(n3) 。
因为 n ≤ 500 n \leq 500 n≤500 ,所以对于组合数和 2 2 2 的 j j j 次方必须用 O ( 1 ) O(1) O(1) 求,也就是提前求好用数组存下来。
dp[1][1] = 1;
for (int i = 2; i <= n - 1; i++)
for (int j = 1; j < i; j++) {
for (int l = 1; l <= i - j; l++)
dp[i][j] = (dp[i][j] + dp[i - j][l] * num[l][j] % MOD * c[n - i - 1 + j][j] % MOD * tp[j * (j - 1) / 2] % MOD) % MOD;
}
for (int j = 1; j < n - 1; j++)//因为是严格小于,所以把终点单独当做一层来算
ans = (ans + dp[n - 1][j] * (tp[j] - 1) % MOD) % MOD;