CQOI2018 社交网络

题目链接:戳我

有向生成树计数。

那么在这里补充一下矩阵树定理吧!

  • 度数矩阵-邻接矩阵(双向计数),去掉任意一行一列,剩下的式子高斯消元之后,对角线乘积是无向图的生成树个数。
  • 入度矩阵-邻接矩阵(单向边),去掉根相关的一行一列,剩下的式子高斯消元之后,对角线乘积是外向树的生成树个数。
  • 出度矩阵-邻接矩阵(单向边),去掉根相关的一行一列,剩下的式子高斯消元之后,对角线成绩是内向树的生成树个数。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 1010
#define mod 10007
using namespace std;
int n,m,ans=1;
int sum[MAXN][MAXN];
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int u,v;
        scanf("%d%d",&v,&u);
        sum[v][v]++;
        sum[u][v]--;
    }
    for(int i=2;i<=n;i++)
    {
        for(int j=i+1;j<=n;j++)
        {
            while(sum[j][i])
            {
                int t=sum[i][i]/sum[j][i];
                for(int k=i;k<=n;k++)
                {
                    sum[i][k]=(sum[i][k]+mod-sum[j][k]*t%mod)%mod;
                    swap(sum[i][k],sum[j][k]);
                }
                ans*=-1;
            }
        }
    }
    for(int i=2;i<=n;i++) ans=1ll*ans*sum[i][i]%mod;
    printf("%d\n",(ans+mod)%mod);
    return 0;
}

posted @ 2019-05-22 23:38  风浔凌  阅读(161)  评论(0编辑  收藏  举报