BZOJ 3659: Which Dreamed It 基尔霍夫矩阵 best theorem

来源:互联网 发布:python作品 编辑:程序博客网 时间:2024/06/17 21:50

3659: Which Dreamed It

Time Limit: 20 Sec  Memory Limit: 1024 MB
Submit: 172  Solved: 49
[Submit][Status][Discuss]

Description

有n个房间,每个房间有若干把钥匙能够打开特定房间的门。
你会做这么件事情:
最初你在房间1。
每当你到达一个房间,你可以选择该房间的一把钥匙,前往该钥匙对
应的房间,并将该钥匙丢到垃圾桶中。
你希望:最终回到房间1,且垃圾桶中有所有的钥匙。
求方案数。两组方案不同,当且仅当使用钥匙的顺序不同。注意,每
把钥匙都是不同的。

Input

 有多组数据。
对于每组数据第一行输入一个数n,表示房间数。
接下来n行依次描述每个房间:
首先一个数s,表示这个房间的钥匙数目,接下来s个数,分别描述每把
钥匙能够打开的房间的门。
输入以n-0结尾。

Output

对于每组数据,输出方案数,为了方便你的输出,请将答案对1000003取模。

Sample Input

1
0
2
1 1
1 2
0

Sample Output

1
0

HINT

在第一组样例中,没有钥匙,则方案数为1。
在第二组样例中,你不可能使用第二个房间的钥匙,所以方案数为0。
房间数小于等于100,钥匙数小于等于200000。
数据组数也不是特别多。


定理题 这定理命名就是最大的槽点

Best Theorem

以某个点为起点的欧拉回路数=该点为根的树形图数*((每个点出度-1 )的阶乘)
这个题再多乘一个d[1]因为不同点出发算不同方案

基尔霍夫矩阵适用于有向图 度数矩阵存出度 邻接矩阵正常搞

重边不怕照样好使 自环删掉 找搞不误

这是今天最后一道矩阵树定理了 吧。。。。

#include<cmath>#include<ctime>#include<cstdio>#include<cstring>#include<cstdlib>#include<complex>#include<iostream>#include<algorithm>#include<iomanip>#include<vector>#include<string>#include<bitset>#include<queue>#include<map>#include<set>using namespace std;typedef long long ll;inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch<='9'&&ch>='0'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}void print(int x){if(x<0)putchar('-'),x=-x;if(x>=10)print(x/10);putchar(x%10+'0');}const int N=110,mod=1000003;int a[N][N],d[N],fac[mod];void initial(){memset(a,0,sizeof(a));memset(d,0,sizeof(d));}int det(int n){register int i,j,k,res=1,x,y,tmp,f=1;for(i=1;i<=n;++i)for(j=1;j<=n;++j)a[i][j]=(a[i][j]+mod)%mod;for(i=1;i<=n;++i){for(j=i+1;j<=n;++j){x=a[i][i],y=a[j][i];while(y){tmp=x/y;x%=y;swap(x,y);for(k=i;k<=n;++k)a[i][k]=((a[i][k]-1ll*tmp*a[j][k])%mod+mod)%mod;for(k=i;k<=n;++k)swap(a[i][k],a[j][k]);f=-f;}}if(!a[i][i])return 0;res=1ll*res*a[i][i]%mod;}if(f==-1)res=mod-res;return (res%mod+mod)%mod;}int main(){register int i,j,v,n=read(),ans;fac[0]=1;for(i=1;i<mod;++i)fac[i]=1ll*fac[i-1]*i%mod;//cout<<n<<endl;while(n){ans=1;for(i=1;i<=n;++i){d[i]=read();for(j=1;j<=d[i];++j){v=read();if(i!=v)a[i][i]++,a[i][v]--;}}if(n==1&&!d[1]){puts("1");n=read();continue;}for(i=1;i<=n;++i)ans=1ll*ans*fac[d[i]-1]%mod;ans=1ll*ans*det(n-1)%mod;ans=1ll*ans*d[1]%mod;print(ans);puts("");n=read();initial();}return 0;}/*1021 11 2010*/