2018-team4-modules-生成树计数
从 Trac 迁移的文章
这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。
原文章内容如下:
{{{
// a[i][j] = D[i][j] - G[i][j]
// 基尔霍夫矩阵a[i][j]为度数矩阵D[i][j]与邻接矩阵G[i][j]的差
// 生成树数目为det(n-1) (a[1..n][1..n])
int a[maxn][maxn];
inline int det(int n){
int ret = 1,s=0;
rep(i,1,n){
rg r = i;
for(r=i;r <= n;++r) if(a[r][i] != 0) break;
if(r == n+1) return 0;
if(r != i){
s ^= 1;
rep(j,i,n) swap(a[r][j],a[i][j]);
}
rep(j,i+1,n){
while(a[j][i]){
int x = a[j][i]/a[i][i];
rep(k,i,n){
a[j][k] -= 1LL*a[i][k]*x % mod;
if(a[j][k] < 0) a[j][k] += mod;
}
if(a[j][i] == 0) break;
s ^= 1;
rep(k,i,n) swap(a[j][k],a[i][k]);
}
}
ret = 1LL*ret*a[i][i] % mod;
}
if(s) ret = mod - ret;
return ret;
}
}}}
// a[i][j] = D[i][j] - G[i][j]
// 基尔霍夫矩阵a[i][j]为度数矩阵D[i][j]与邻接矩阵G[i][j]的差
// 生成树数目为det(n-1) (a[1..n][1..n])
int a[maxn][maxn];
inline int det(int n){
int ret = 1,s=0;
rep(i,1,n){
rg r = i;
for(r=i;r <= n;++r) if(a[r][i] != 0) break;
if(r == n+1) return 0;
if(r != i){
s ^= 1;
rep(j,i,n) swap(a[r][j],a[i][j]);
}
rep(j,i+1,n){
while(a[j][i]){
int x = a[j][i]/a[i][i];
rep(k,i,n){
a[j][k] -= 1LL*a[i][k]*x % mod;
if(a[j][k] < 0) a[j][k] += mod;
}
if(a[j][i] == 0) break;
s ^= 1;
rep(k,i,n) swap(a[j][k],a[i][k]);
}
}
ret = 1LL*ret*a[i][i] % mod;
}
if(s) ret = mod - ret;
return ret;
}