zoukankan      html  css  js  c++  java
  • [模板]矩阵树定理

    用途

    求生成树个数

    做法

    定义度数矩阵A,A[i][i]为i号点的度数;邻接矩阵B,B[i][j]为点i到j的边数

    对于无向图,用A-B,然后随意选一个i,去掉第i行和第i列,它的行列式就是生成树个数

    对于有向图,外向树的个数就是把度数矩阵换成入度矩阵;内向树的个数就是换成出度矩阵;删掉的行列一定要是根

    行列式求法

    首先有三条内容:

    1.交换矩阵的两行,行列式取反

    2.用矩阵一行加减一行的倍数,行列式不变

    3.上三角矩阵的行列式为主对角线元素的积

    于是可以高斯消元成上三角矩阵

    例题

    bzoj4894 天赋(有向图外向树个数)

     1 #include<bits/stdc++.h>
     2 #include<tr1/unordered_map>
     3 #define CLR(a,x) memset(a,x,sizeof(a))
     4 #define MP make_pair
     5 using namespace std;
     6 typedef long long ll;
     7 typedef unsigned long long ull;
     8 typedef pair<int,int> pa;
     9 const int maxn=305,P=1e9+7;
    10 
    11 inline ll rd(){
    12     ll x=0;char c=getchar();int neg=1;
    13     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
    14     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    15     return x*neg;
    16 }
    17 
    18 int N,a[maxn][maxn];
    19 char s[maxn];
    20 
    21 inline int fpow(int x,int y){
    22     int re=1;
    23     while(y){
    24         if(y&1) re=1ll*x*re%P;
    25         x=1ll*x*x%P,y>>=1;
    26     }return re;
    27 }
    28 
    29 int main(){
    30     //freopen("","r",stdin);
    31     N=rd();
    32     for(int i=1;i<=N;i++){
    33         scanf("%s",s+1);
    34         for(int j=2;j<=N;j++){
    35             if(s[j]=='1'){
    36                 a[j-1][j-1]++;
    37                 if(i!=1) a[i-1][j-1]--;
    38             }
    39         }
    40     }N--;
    41     int ans=1;
    42     for(int i=1;i<=N;i++){
    43         int mi=i;
    44         for(int j=i+1;j<=N;j++){
    45             if(a[j][i]) mi=j;
    46         }
    47         if(mi!=i) ans*=-1,swap(a[mi],a[i]);
    48         for(int j=i+1;j<=N;j++){
    49             int r=1ll*a[j][i]*fpow(a[i][i],P-2)%P;
    50             for(int k=i;k<=N;k++){
    51                 a[j][k]=(a[j][k]-1ll*a[i][k]*r)%P;
    52             }
    53         }
    54     }
    55     for(int i=1;i<=N;i++) ans=1ll*ans*a[i][i]%P;
    56     printf("%d
    ",(ans+P)%P);
    57     return 0;
    58 }
  • 相关阅读:
    Java基础系列1:Java基本类型与封装类型
    深入理解设计模式六大原则
    分布式系统ID生成方案汇总
    微服务入门
    Web攻击技术
    Jedis与Redisson选型对比
    Hystrix分布式系统限流、降级、熔断框架(二)
    可重入锁ReentrantLock实现原理
    Hystrix分布式系统限流、降级、熔断框架(一)
    Redis过期策略、持久化、集群与常见缓存问题
  • 原文地址:https://www.cnblogs.com/Ressed/p/10276764.html
Copyright © 2011-2022 走看看