BZOJ 4894: 天赋 矩阵树定理

code:

#include <cstring>
#include <cstdio>
#include <algorithm>
#define N 303   
#define mod 1000000007         
#define ll long long
#define setIO(s) freopen(s".in","r",stdin)
using namespace std; 
char S[N];   
int a[N][N],n;              
int qpow(int x,int y)
{
    int tmp=1;
    for(;y;y>>=1,x=(ll)x*x%mod)
        if(y&1) tmp=(ll)tmp*x%mod;   
    return tmp;
}
int INV(int x) { return qpow(x,mod-2); }
int gauss()
{
    int ans=1,i,j,k;    
    for(i=2;i<=n;++i)
    {
        k=i;
        for(j=i+1;j<=n;++j)  if(a[j][i]>a[k][i]) k=j;  
        if(k!=i) swap(a[i],a[k]),ans*=-1;   
        if(!a[i][i]) return 0;   
        int inv=INV(a[i][i]);       
        for(j=i+1;j<=n;++j)
        {
            int t=(ll)((ll)inv*a[j][i]%mod+mod)%mod;   
            for(k=i;k<=n;++k) a[j][k]=(ll)(a[j][k]%mod-(ll)t*a[i][k]%mod+mod)%mod;        
        }
    }
    if(ans<0) ans+=mod;    
    for(i=2;i<=n;++i) ans=(ll)((ll)ans*a[i][i]%mod+mod)%mod;   
    return ans;  
}    
int main()
{
    // setIO("input");
    int i,j;
    scanf("%d",&n);  
    for(i=1;i<=n;++i) 
    {
        scanf("%s",S+1);   
        for(j=1;j<=n;++j)  
        {
            if(S[j]=='1') // i->j    
            {    
                ++a[j][j];    
                --a[i][j];     
            }                   
        }
    }
    printf("%d\n",gauss());    
    return 0;
}

  

posted @ 2020-02-03 17:57  EM-LGH  阅读(126)  评论(0编辑  收藏  举报