记录一种DAG计数方法与一个配套技巧

记录一种DAG计数方法与一个配套技巧

定义 fS 表示集合 S 中的点构成的合法 DAG 子图的方案数。假设找到 DAG 中一个入度为 0 的节点 x,那么很明显 fS=xfS{x},这明显要算重因为 S{x} 中也有入度为 0 的点。

于是有一个容斥的想法,设 DAG 中一个入度为 0 的点集至少是 T,根据容斥的思想,其应该贡献 (1)|T|+1 的权值

于是有表达式 fS=TS,TfST(1)|T|+1


技巧:一个判断点集 T 是否能到点集 S 的方法:记录所有可以到点集 S 的点的集合 from[S],直接看 Tfrom[S]= 即可。

注意:c++ 中 & 运算的优先级低于 == 运算。


P6846 [CEOI 2019] Amusement Park

CF1193A Amusement Park 与这道题是双倍经验

用一种对称的观点看,我们发现若存在一种翻转 x 条边的方案,那么一定存在另一种翻转 mx 条边的方案,那么问题变成了:给定一个无向图,你可以给边定向,求无向图个数,最后乘上 m2

于是设 fS 表示点集 S 构成的子图的合法 DAG 数量,根据上面的方法,有 fS=TS,T(1)|T|+1fST×c(T) 其中 c(T) 表示 T 集合中是否两两无边。

AT_abc306_h [ABC306Ex] Balance Scale

如果不考虑 =,那么容易发现答案不合法当且仅当有同序的关系构成了一个环,于是这就是一个 DAG 计数,与上一道题是一模一样的。

容易发现添加了 = 后,相当于把几个点构成的子连通块合并在了一起,类比一下,发现可以把这样一个连通块当作一个“点”进行添加,即:

同理配容斥系数,设 cntT 表示一个点集 T 的子图联通块数,则:

fS=TS,T(1)cntT+1fST

O(3n) 已经可以解决这道题。

更优的复杂度:发现这是一个子集卷积,用子集卷积可以做到 O(2nn2) 的复杂度。

[学习笔记]子集卷积 - epic01 - 博客园

TG178X 的模拟赛题“单独行动”

题目:给一个 n 个点,m 条边的无向图,每条边 (u,v) 分别有 13 的概率变为 uv,vu 和消失,求最后为 DAG 的概率。

n20

首先按照方法设出 dp 并写出转移式:

fS=TS,TfST2E(S)E(T)E(ST)(1)|T|+1

其中 E(S) 表示两端都在 S 中边数。这道题 O(3n) 过不了。

将式子变为:

fS2E(S)=TS(1)|T|+12E(T)fST2E(ST)

这可以子集卷积,复杂度 O(2nn2)

P10221 [省选联考 2024] 重塑时光

不难发现 k=0 就是 DAG 拓扑排序数,用一个简单的状压 DP 即可解出。

k0 时,相当于将点集分成了小于等于 k 块(先不考虑空集),求块内是合法的 DAG 拓扑排序,块间不存在环的方案数。“不存在环”就是 DAG,块间变成了一个 DAG 计数,而块内我们已经解决了,这是一个正确的思路。

S 块内重排列满足条件的方案数为 hS,有:

hS=TShT×c(T,ST)

其中 c(S,T) 表示 S 不能到 T

gS,i 表示把 S 中的点分成 i 块使得其中块间两两无边的方案数,有:

gS,i=TSgST,i1×c(T,ST)×c(ST,T)

fS,i 表示把 S 中的点分成 i 块使得构成 DAG 的方案数,有:

fS,i=TSc(T,ST)×c(ST,T)×j=0ifST,ijgS,j

最终答案为 k!(k+1)!(n+k)!ifU,i(k+1i)!

于是可以在 O(n23n) 的时间复杂度下求解,然而还可以更快。

容易发现上面的转移式是一个卷积。设 FS(x)=ifS,ixi,GS(x)=igS,i(1)i+1xi,则上述转移式可以改写为:

FS(x)=TSFST(x)GS(x)

nx 进去求出值后,再用拉格朗日插值求出系数即可。

复杂度 O(n3n+n22n)

P6295 有标号 DAG 计数

先咕

【清华集训2014】主旋律

这是求强连通的子图,我们知道强连通图缩点后就是一个点,而非强连通图缩点后就是DAG,于是可以通过 DAG 计数的方法计算出非强连通图的个数后,从而得到强连通图的个数。

fS 表示点集 S 的强连通子图的方案数,可以套路的列出下列式子:

fS=2E(S,S)TS,T2E(T,ST)+E(ST,ST)gT

其中 E(S,T)=|{(u,v)|uS,vT}|

gT 是点集 T 的带容斥系数的分成若干强连通分量的方案数,这里的容斥系数本来应该是 (1)+1,但由于并不知道具体强连通分量数,只能如此处理。枚举其中一个元素所在的强连通块,有如下式子:

gS=TS,maxSTfTgST

注意:

  • 根据定义 fSggS 的更新应该放在 fS 处理完毕之后。

  • g=1

代码:提交记录 #739694

HDU 4997 Biconnected

题意:给一张图,问有多少种加边的方法,使得图是边双。

GYM 102331C Counting Cactus

题意:给一张图(无重边自环),求有多少个边的子集使得没有任何一条边在两个环中。 (生成边仙人掌计数)


一个参考文章:一类图论相关的状压 DP 题的常见解法 - Mackerel_Pike - 博客园,里面说这种方法不仅可以运用在DAG计数,还可以运用在连通图、强连通、双连通图的计数与最优化上。其中计数问题需要容斥,最优化问题则不需要。

作者:lupengheyyds

出处:https://www.cnblogs.com/lupengheyyds/p/18714243

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   lupengheyyds  阅读(62)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
点击右上角即可分享
微信分享提示