【模板】矩阵树定理-生成树计数
Matrix-Tree 定理作用:给定 n 个点 m 条边的无向图,求图的生成树个数。
定义矩阵K[i][j]=D[i][j]-A[i][j],(其中D为度数矩阵(即当i==j时,D[i][j]=节点 i 的度数,其余为0),A为邻接矩阵,有边相邻即为1,其余为0)
结论:对于已经得出的基尔霍夫矩阵,去掉其随意一行一列得出的矩阵的行列式,其绝对值为生成树的个数
注:行列式的绝对值:先用高斯消元消成上三角矩阵,把对角线乘起来
文章:https://wenku.baidu.com/view/872eb02de2bd960590c677c6.html
#include <bits/stdc++.h>
#define fuck system("pause")
#define emplace_back push_back
#define pb push_back
using namespace std;
typedef long long ll;
const ll mod = 998244353;
const double eps = 1e-6;
const ll inf = 0x3f3f3f3f;
const ll N = 2e5 + 10;
ll mat[110][110];
ll gauss(ll n){
ll ans = 1;
for (ll i = 1; i < n;i++){
for (ll j = i + 1; j < n; j++) {
while(mat[j][i]){
ll t = mat[i][i] / mat[j][i];
for (ll k = i; k < n;k++){
mat[i][k] = (mat[i][k] - t * mat[j][k] + mod) % mod;
}
swap(mat[i], mat[j]);
ans = -ans;
}
}
ans = (ans * mat[i][i]) % mod;
}
return (ans + mod) % mod;
}
int main(){
ll n,m;
scanf("%lld%lld", &n, &m);
for (ll i = 1;i<=m;i++){
ll u,v;
scanf("%lld%lld", &u, &v);
mat[u][u]++, mat[v][v]++;
mat[u][v]--, mat[v][u]--;
}
ll num = gauss(n);
printf("%lld\n",num);
return 0;
}