SCL--生成树计数(Matrix-Tree定理)

2015-09-07 20:52:51

总结:2012 多校#1 的 F题遇到的生成树计数,学习一下~

  相关学习资料:周冬论文博客比较好的code

  生成树计数方法较多,然而由Matrix-Tree定理(Kirchhoff矩阵-树定理),我们可以得到一个非常有效率的算法。它首先于1847年被Kirchhoff证明。

  适用于无自环、重边。

  我们先定义矩阵D为度数矩阵(n×n),D[i][i] = deg(i)(i的度数),D[i][j] = 0(i != j)

     以及矩阵G为邻接矩阵(n×n),G[i][j] = 1(i与j之间有边相连),G[i][j] = 0(i与j间无边)。

  然后让D矩阵减去G矩阵,得到A矩阵,那么生成树的方案数为A的(n-1)阶主子式的行列式的值。

  因为A矩阵的特殊性,所以我们可以用整数形式的消元来求行列式的值。

 

下面是HDU4305核心代码部分。  

注意:在调用Det函数时应该传n-1(代表A矩阵的n-1阶主子式)

int Det(int n){
    int A[MAXN][MAXN];
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= n; ++j)
            A[i][j] = G[i][j];
    int res = 1;
    for(int i = 1; i <= n; ++i){
        for(int j = i + 1; j <= n; ++j){
            while(A[j][i]){
                int t = A[i][i] / A[j][i];
                for(int k = i; k <= n; ++k)
                    A[i][k] = (A[i][k] - A[j][k] * t) % mod;
                for(int k = i; k <= n; ++k)
                    swap(A[i][k],A[j][k]);
                res = -res; //行列式换行,值取反
            }
        }
        if(!A[i][i]) return 0;
        res = res * A[i][i] % mod;
    }
    return (res + mod) % mod;
}

 

转载于:https://www.cnblogs.com/naturepengchen/articles/4790042.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值