BZOJ5297 CQOI2018社交网络(矩阵树定理)

  板子题。

#include<iostream> 
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 256
#define P 10007
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
    int x=0,f=1;char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    return x*f;
}
int n,m,degree[N],inv[P];
struct matrix
{
    int a[N][N];
    int value()
    {
        int s=1;
        for (int i=2;i<=n;i++)
            for (int j=2;j<=n;j++)
            a[i][j]=(a[i][j]%P+P)%P;
        for (int i=2;i<=n;i++)
        {
            if (!a[i][i])
            for (int j=i+1;j<=n;j++)
            if (a[j][i]) {swap(a[i],a[j]);s=-s;break;}
            for (int j=i+1;j<=n;j++)
            {
                int t=1ll*a[j][i]*inv[a[i][i]]%P;
                for (int k=i;k<=n;k++)
                a[j][k]=((a[j][k]-a[i][k]*t)%P+P)%P;
            }
        }
        for (int i=2;i<=n;i++) s=1ll*s*a[i][i]%P;
        return (s+P)%P;
    }
}a;
int main()
{
#ifndef ONLINE_JUDGE
    freopen("bzoj5297.in","r",stdin);
    freopen("bzoj5297.out","w",stdout);
    const char LL[]="%I64d\n";
#else
    const char LL[]="%lld\n";
#endif    
    n=read(),m=read();
    for (int i=1;i<=m;i++)
    {
        int x=read(),y=read();
        a.a[y][x]--;degree[x]++;
    }
    for (int i=1;i<=n;i++) a.a[i][i]+=degree[i];
    inv[1]=1;for (int i=2;i<P;i++) inv[i]=P-(P/i)*inv[P%i]%P;
    cout<<a.value();
    return 0;
}

 

posted @ 2018-12-12 13:11  Gloid  阅读(156)  评论(0编辑  收藏  举报