带边数的无向连通图计数

就是求 n 个点 m 条边的带标号无向连通图个数。

首先可以用最暴力的 O(n6) 做法,直接按城市规划一题的容斥 DP 做法,
fn,m 表示答案,可以枚举 1 号点所在块的情况容斥计算。

O(n4) 做法是一个有意思的斯特林反演。

考虑一个选了 m 条边的方案,且形成 k 个连通块方案块的方案是 Fm,k
现在我们还是 m 条边,但人为划分出来 j 个块一定不两两相连,但块内任意连边,方案是 Gm,j

有组合关系:

Gm,k=jkS2(j,k)Fm,j

反演以后即:

Fm,k=jkS1(j,k)(1)jkGm,j

我们要求的即:

Fm,1=j1(j1)!(1)j1Gm,j

考虑 DP 后面那个 G,暴力大概不止 O(n6)
但是我们发现算这个 G 只需要知道块的划分情况,那么这 m 条边的可以随意选取。
Hi,j,m 表示 DP 了 i 个点,分了 j 个块,当前共有 m 个边可以用的方案数。

则有:

Gm,j=kmHn,j,k(km)

直接 DP 这个 H 复杂度过高,接下来尝试缩去中间 j 那一维。
现在考虑把 (j1)!(1)j1 的附加贡献在 DP 过程中算上,
发现我们可以先正常选一个块,并固定这个块的一号在最前面,
然后剩下的每加入一个块,带一个 1 的系数并且把这个块的点任意插进去(只需保证不在开头,系数 (i+k1k))进行 DP。
这样就做到让一个 k 个块的方案会算重 (k1)! 次。
时间复杂度 O(n4)

然而代码短小精悍。

posted @   bestwyj  阅读(1659)  评论(1编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示