题目描述:
给一个无向图,求图上生成树的数量.
题目分析:
矩阵树定理就是用于解决图上的生成树的计数问题的.
先构造两个矩阵
A为邻接矩阵 若 u v 有边 A[u][v]++ A[v][u]++
B为度数矩阵 若 u v 有边 则 B[u][u]++ B[v][v]++
最后构造矩阵 C=B-A
删去矩阵C任意元素
Ci,j
C
i
,
j
所在的行列
求这个矩阵的行列式的绝对值即为答案!
没有取模,有取模的高斯消元不太一样…
具体介绍等我学明白了,再写一篇博客吧…
题目链接:
Ac 代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#define ll long long
const int maxm=20;
ll C[maxm][maxm],d[maxm];
int n,m;
inline ll Matrix_Tree(ll a[][maxm])
{
ll ret=1;
for(int i=2;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
while(a[j][i])
{
ll t=a[i][i]/a[j][i];
for(int k=i;k<=n;k++)
a[i][k]=(a[i][k]-a[j][k]*t);
for(int k=i;k<=n;k++)
std::swap(a[i][k],a[j][k]);
ret=-ret;
}
if(!a[i][i]) return 0;
ret=ret*a[i][i];
}
return ret<0?-ret:ret;
}
inline void work()
{
memset(C,0,sizeof(C));
memset(d,0,sizeof(d));
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
C[u][v]=-1;
C[v][u]=-1;
d[u]++,d[v]++;
}
for(int i=1;i<=n;i++)
C[i][i]=d[i];
printf("%lld\n",Matrix_Tree(C));
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
work();
return 0;
}