P4455 [CQOI2018]社交网络

【题意】

求一个有向图的外向树个数

【分析】

矩阵树定理板子题,具体见这里

【代码】

#include<bits/stdc++.h>
using namespace std;
#define mp make_pair
#define fi first
#define se second
#define lson now<<1
#define rson now<<1|1
typedef long long ll;
const int mod=1e4+7;
int f[262][262];
int n,m;
int qpow(int a,int b)
{
    int res=1;
    while(b)
    {
        if(b&1) res=1LL*res*a%mod;
        a=1LL*a*a%mod;
        b>>=1;
    }
    return res;
}
int ans=1,fl=1;
void calc()
{
    for(int i=1;i<=n;i++)
    {
        int mx=i;
        for(int j=i+1;j<=n;j++)
            if(f[j][i]>f[mx][i])
                mx=j;
        if(mx!=i)
        {
            for(int j=1;j<=n;j++)
                swap(f[mx][j],f[i][j]);
            fl*=-1;
        }
        if(!f[i][i])
        {
            ans=0;
            return;
        }
        int inv=qpow(f[i][i],mod-2);
        for(int j=i+1;j<=n;j++)
        {
            if(!f[j][i]) continue;
            int tmp=1LL*f[j][i]*inv%mod;
            for(int k=i;k<=n;k++)
                f[j][k]=((f[j][k]-1LL*tmp*f[i][k]%mod)%mod+mod)%mod;
        }
    }
    for(int i=1;i<=n;i++) ans=1LL*ans*f[i][i]%mod;
    ans=(ans*fl%mod+mod)%mod;
    return;
}
signed main()
{
    // freopen("a.in","r",stdin);
    // freopen("a.out","w",stdout);
    scanf("%d%d",&n,&m);
    int x,y;   
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        x--; y--;
        f[y][x]=(f[y][x]-1+mod)%mod;
        f[x][x]=(f[x][x]+1)%mod;
    }
    n--;
    calc();
    printf("%d",ans);
    return 0;
}

 

posted @ 2021-05-27 16:13  andyc_03  阅读(323)  评论(0编辑  收藏  举报