题目链接
https://www.lydsy.com/JudgeOnline/problem.php?id=3812
题解
考虑求非强连通子图的数量,假设为ggg,那么答案就是2m−g2^m-g2m−g。现在考虑求ggg。
假设fsf_sfs表示用sss这些点能构成的强连通图的个数,gsg_sgs表示用sss这些点能构成的非强连通图的方案数,其中构成iii个强连通分量则对gsg_sgs的贡献为(−1)i(-1)^i(−1)i。容易发现
gs=fs−∑t⊂s,u∈tgtfs−t g_s=f_s-\sum_{t\subset s,u\in t} g_tf_{s-t} gs=fs−t⊂s,u∈t∑gtfs−t
那么
fs=2es−∑t⊆s,t̸=∅2es−t+es−t,tgs f_s=2^{e_s}-\sum_{t\subseteq s,t\not= \varnothing}2^{e_{s-t}+e_{s-t,t}}g_s fs=2es−t⊆s,t̸=∅∑2es−t+es−t,tgs
容易发现,fsf_sfs此时需要的是不包含fsf_sfs的gsg_sgs,因此gsg_sgs在求出fsf_sfs之前是不能+fs+f_s+fs的。
代码
#include <cstdio>
int read()
{
int x=0,f=1;
char ch=getchar();
while((ch<'0')||(ch>'9'))
{
if(ch=='-')
{
f=-f;
}
ch=getchar();
}
while((ch>='0')&&(ch<='9'))
{
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
const int maxn=15;
const int maxm=1<<maxn;
const int mod=1000000007;
int n,m,f[maxm+10],g[maxm+10],pow[maxn*maxn+10],ecnt[maxm+10][maxn+2],in[maxm+10];
inline int lowbit(int x)
{
return x&(-x);
}
int main()
{
n=read();
m=read();
int full=(1<<n)-1;
for(int i=1; i<=m; ++i)
{
int a=read(),b=read();
for(int j=1; j<=full; ++j)
{
if((1<<(a-1))&j)
{
++ecnt[j][b];
}
}
}
pow[0]=1;
for(int i=1; i<=m; ++i)
{
pow[i]=pow[i-1]<<1;
if(pow[i]>=mod)
{
pow[i]-=mod;
}
}
f[0]=g[0]=1;
for(int s=1; s<=full; ++s)
{
int sk=s^lowbit(s);
for(int t=sk; t; t=sk&(t-1))
{
g[s]-=1ll*f[s^t]*g[t]%mod;
if(g[s]<0)
{
g[s]+=mod;
}
}
for(int i=1; i<=n; ++i)
{
if((1<<(i-1))&s)
{
in[s]+=ecnt[s][i];
}
}
f[s]+=pow[in[s]];
for(int t=s; t; t=s&(t-1))
{
int e=0;
for(int i=1; i<=n; ++i)
{
if((1<<(i-1))&t)
{
e+=ecnt[s^t][i];
}
}
f[s]-=1ll*pow[e+in[s^t]]*g[t]%mod;
if(f[s]<0)
{
f[s]+=mod;
}
}
g[s]+=f[s];
if(g[s]>=mod)
{
g[s]-=mod;
}
}
printf("%d\n",f[full]);
return 0;
}