题目大意
求原图有多少子图是强连通分量。
题目分析
%Miskoo,注意其中$f$函数被使用了两次,但代表的意义不同。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| #include<algorithm> #include<iostream> #include<iomanip> #include<cstring> #include<cstdlib> #include<climits> #include<vector> #include<cstdio> #include<cmath> #include<queue> using namespace std;
typedef long long LL;
inline const int Get_Int() { int num=0,bj=1; char x=getchar(); while(x<'0'||x>'9') { if(x=='-')bj=-1; x=getchar(); } while(x>='0'&&x<='9') { num=num*10+x-'0'; x=getchar(); } return num*bj; }
#define lowbit(x) ((x)&(-(x)))
const int maxn=32768+5; const LL mod=1e9+7;
int n,m,Out[maxn],In[maxn],Pow[505],bitcnt[maxn]; LL f[maxn],g[maxn],h[maxn],p[maxn];
int main() { n=Get_Int(); m=Get_Int(); for(int i=1; i<=m; i++) { int x=1<<(Get_Int()-1),y=1<<(Get_Int()-1); Out[x]|=y; In[y]|=x; } Pow[0]=1; for(int i=1; i<=n*n; i++)Pow[i]=(Pow[i-1]<<1)%mod; bitcnt[0]=0; for(int i=1; i<(1<<n); i++)bitcnt[i]=bitcnt[i^lowbit(i)]+1; for(int S=1; S<(1<<n); S++) { int u=lowbit(S),v=S^u; for(int T=v; T; T=(T-1)&v)g[S]=(g[S]-f[S^T]*g[T]%mod+mod)%mod; h[S]=h[v]+bitcnt[In[u]&v]+bitcnt[Out[u]&v]; f[S]=Pow[h[S]]; for(int T=S; T; T=(T-1)&S) { if(T!=S) { int u=lowbit(S^T); p[T]=p[T^u]+bitcnt[Out[u]&T]-bitcnt[In[u]&(S^T)]; } else p[T]=0; f[S]=(f[S]-Pow[h[S^T]+p[T]]*g[T]%mod+mod)%mod; } g[S]=(g[S]+f[S])%mod; } printf("%lld\n",f[(1<<n)-1]); return 0; }
|