首页 技术 正文
技术 2022年11月9日
0 收藏 903 点赞 2,340 浏览 2095 个字

题意:有一张n个点的无向图,点有标号。求满足下列性质的图有多少个。

1.任意节点到1的最短路唯一。2.i的最短路长度<=i+1的最短路长度。3.所有点的度数给定,为2或3。

n<=400.

标程:

 #include<bits/stdc++.h>
using namespace std;
const int mod=1e9+;
const int inv2=5e8+;
typedef long long ll;
const int N=;
int n,jc[N],inv[N],sum2[N],sum3[N],d,g[N][N][N],f[N][N],ans;
void up(int &x,int y){x=((ll)x+y)%mod;}
int c(int x,int y){return (ll)jc[x]*inv[y]%mod*inv[x-y]%mod;}
int main()
{
scanf("%d",&n);
for (int i=;i<=n;i++)
{
scanf("%d",&d);sum2[i]=sum2[i-];sum3[i]=sum3[i-];
(d==)?sum2[i]++:sum3[i]++;
if (i==) f[d+][d]=;
}
jc[]=jc[]=inv[]=inv[]=;
for (int i=;i<=n;i++) jc[i]=(ll)jc[i-]*i%mod,inv[i]=(ll)(mod-mod/i)*inv[mod%i]%mod;
for (int i=;i<=n;i++) inv[i]=(ll)inv[i-]*inv[i]%mod;
g[][][]=;
for (int i=;i<=n;i++)
for (int j=;j<=i;j++)
up(g[][][i],(ll)g[][][i-j]*c(i-,j-)%mod*jc[j-]%mod*inv2%mod);
for (int i=;i<=n;i+=)
up(g[][i][],(ll)(i-)*g[][i-][]%mod);
for (int j=;j<=n;j++)
for (int k=;k<=n-j;k++)
{
if (j>=) up(g[][j][k],(ll)(j-)*g[][j-][k]%mod);
if (k) up(g[][j][k],(ll)k*g[][j][k-]%mod);
}
for (int i=;i<=n;i++)
for (int j=;j<=n-i;j++)
for (int k=;k<=n-i-j;k++)
{
if (j) up(g[i][j][k],(ll)j*g[i-][j-][k]%mod);
if (k) up(g[i][j][k],(ll)k*g[i-][j+][k-]%mod);
}
for (int i=;i<=n;i++)//考虑前i个点
{
for (int j=;j<i-;j++)//j个一层
for (int k=;k<i-j;k++)//上一层k个
up(f[i][j],(ll)f[i-j][k]*g[j][sum2[i-j]-sum2[i-j-k]][sum3[i-j]-sum3[i-j-k]]%mod);
}
for (int i=;i<n;i++)
up(ans,(ll)f[n][i]*g[][sum2[n]-sum2[n-i]][sum3[n]-sum3[n-i]]%mod);
printf("%d\n",ans);
return ;
}

易错点:1.注意f[][]的初始化,设第一个点的度数为d,f[d+1][d]=1。

2.当dp转移式较为复杂时,考虑辅助数组来降低复杂度。

题解:dp

建立最短路树,发现同一层点的编号连续(因此可以区间dp)。由“最短路唯一”的性质可以得到,非树边一定是同层之间互连。

对于某一层的点,剩下度为1和2的点各有多少个可以互连要根据下一层有多少个儿子决定。

f[i][j]表示前i个点,j个点在当前的最后一层,最后一层没有互连的方案数。g[i][j][k]表示这一层有i个点,上一层有j个剩下度为1的点,k个剩下度为2的点。

显然f[i][j]=sigma(f[i-j][k]*g[j][k1][k2])。统计答案的时候就累加f[n][i]*g[0][k1][k2]即可。

预处理g:1.考虑如果只存在>=3个剩下度为2的点,那么必然构成环:枚举第k个元素所在的环,g[0][0][k]=sigma(g[0][0][k-l]*C(k-1,l-1)*(l-1)!/2);(最后一项是圆排列去重)

2.如果只存在剩下度为1的点,那么一定是两两连边:g[0][j][0]=(j-1)*g[0][j-2][0]。j一定是偶数。

3.如果度为1和2的点都有,而且没有下一层:任意选取一个度为1的点,它与度为1的点或度为2的点连边:g[0][j][k]=(j-1)*g[0][j-2][k]+k*g[0][j][k-1].(连度为1的,少了2个度为1的点;连度为2的点,少了一个度为2的点,度为1的点+1-1不变)

4.普遍情况:任意选取i个点中的一个,考虑和度为1的连边还是和度为2的点连边:g[i][j][k]=j*g[i-1][j-1][k]+k*g[i-1][j+1][k-1].

时间复杂度O(n^3)。

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,000
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,512
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,358
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,141
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,771
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,849