LGP6846 [CEOI 2019] 游乐园 学习笔记
LGP6846 [CEOI 2019] 游乐园 学习笔记
前言
状压图计数的入门题,大概?
题意简述
给定一个 \(n\) 点 \(m\) 边的简单有向图 \(G\)。可以任意反转 \(G\) 中的边。问所有定向使得图 \(G\) 为 \(\texttt{DAG}\) 的方案需要反转的边数的和。答案对 \(998244353\) 取模。
\(n\le 18\),\(m\le\frac{n(n-1)}{2}\)。无重边或自环。
做法解析
如果你足够善于观察题面或题解,你会发现对于每一种合法定向方案 \(A\) 而言,将其所有边反转得到的另一种方案 \(A'\) 也合法,而且 \(A\) 和 \(A'\) 需要反转的边数加起来刚好等于 \(m\)(每一条边如果在 \(A\) 是正着的,那在 \(A'\) 就是反着的;反之亦然)。所以题目就转化为求合法方案数乘上 \(\frac{m}{2}\)。
转化后的问题:给定一个 \(n\) 点 \(m\) 边的图 \(G\),可以任意给边定向,问有多少种方案使得图 \(G\) 为 \(\texttt{DAG}\)。
这玩意怎么求?\(n\le 18\),这启示我们使用状压 DP。关于 \(\texttt{DAG}\) 状压计数一个常见套路(必记!)是:钦定零度点集,简单容斥去重。什么意思呢?
我们设 \(F_S\) 为 定向点集 \(S\) 内的边使得 \(S\) 为 \(\texttt{DAG}\) 的方案数。我们既然要考虑其转移,就要分析 \(\texttt{DAG}\) 的性质:每一个 \(\texttt{DAG}\) 肯定都包含一些入度为 \(0\) 的点(也就是做拓扑排序时最先入队列的那一批点),这些点必须是一个独立集(即两两没有边相连)。如下图中的 \(T\) 就是一个独立集。

因为每个方案都有其零度点点集,我们就考虑通过枚举零度点点集 \(T\) 来计数。
我们钦定 \(T\) 和 \(S-T\) 间的所有边都由 \(T\) 连向 \(S-T\)。对于一种合法方案而言,\(S-T\) 也得是个 DAG。这样我们就有:\(F_S=\sum_{T\subset S,T\neq\varnothing}F_{S-T}\)。
对吗?不对,会算重。比如下图的这种方案就被算了三次。

解决办法?上容斥。由容斥原理,当点集 \(T\) 的大小为奇数时,我们令它贡献为正,否则贡献为负。也就是说现在的转移式子是:\(F_S=\sum_{T\subset S,T\neq\varnothing}(-1)^{|T|-1}F_{S-T}\)。
然后,这道题就做完了!
代码实现
代码内dp数组即为上文的 \(F\);vis[s]指点集s是否为独立集,对其判断可以在 \(O(m2^n)\) 的时间复杂度内完成,详见代码。
#include <bits/stdc++.h>
using namespace std;
using namespace obasic;
using namespace omodint;
using mint=M998;
const int MaxN=18,MaxNa=1<<18;
int N,alf,M,X,Y,Gr[MaxN],ppc[MaxNa],vis[MaxNa];mint dp[MaxNa];
void addudge(int u,int v){Gr[u]|=(1<<v),Gr[v]|=(1<<u);}
int main(){
    readis(N,M);alf=(1<<N)-1;
    for(int i=1;i<=alf;i++)ppc[i]=ppc[i/2]+(i&1);
    for(int i=1;i<=M;i++)readis(X,Y),addudge(X-1,Y-1);
    vis[0]=1;
    for(int s=1;s<=alf;s++){
        for(int u=0;u<N;u++){
            if(((1<<u)&s)&&(!(Gr[u]&s)))vis[s]|=vis[s-(1<<u)];
        }
    }
    dp[0]=1;
    for(int s=1;s<=alf;s++){
        for(int t=s;t;t=(t-1)&s){
            if(vis[t])dp[s]+=dp[s-t]*(ppc[t]&1?1:-1);
        }
    }
    writi(miti(dp[alf]*M/2));
    return 0;
}
反思总结
\(\texttt{DAG}\) 状压计数套路:钦定零度点集,简单容斥去重!!!
 
                    
                 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号