构建基尔霍夫矩阵,基尔霍夫矩阵的任意一个代数余子式是所有生成树的边权积的和,也就是求的是(sumlimits_Tprodlimits_{ein T}v_e)
无向图
基尔霍夫矩阵为度数矩阵减去邻接矩阵
任意去掉一行一列,所得到的矩阵的行列式即为所求
有向图
外向树为入度矩阵减去邻接矩阵
内向树出度矩阵减去邻接矩阵
删去根所在的行和列,所得到的矩阵的行列式即为所求
构建矩阵时,一条边对矩阵的贡献为其边权
行列式
转置矩阵,行列式不变
交换两行或两列的位置,行列式取相反数
对一行或一列乘以某数,行列式也乘以某数
用一行的倍数减去另一行,行列式的值不变
上三角矩阵的行列式的值等于对角线的乘积
利用这些性质将矩阵消为上三角矩阵后,即可求得行列式
(code:)
ll det()
{
ll ans=1;
for(int i=2;i<=n;++i)
{
for(int j=i+1;j<=n;++j)
{
while(a[j][i])
{
ll d=a[i][i]/a[j][i];
for(int k=i;k<=n;++k)
a[i][k]=((a[i][k]-a[j][k]*d%mod)%mod+mod)%mod;
swap(a[i],a[j]),ans*=-1;
}
}
ans=ans*a[i][i]%mod;
}
return (ans%mod+mod)%mod;
}
double det()
{
n--;
double ans=1;
for(int i=1;i<=n;++i)
{
int ma=i;
for(int j=i+1;j<=n;++j)
if(fabs(a[j][i])>fabs(a[ma][i]))
ma=j;
if(ma!=i) swap(a[ma],a[i]),ans*=-1;
if(fabs(a[i][i])<eps) return 0;
for(int j=i+1;j<=n;++j)
{
double d=a[j][i]/a[i][i];
for(int k=i;k<=n;++k)
a[j][k]-=a[i][k]*d;
}
ans*=a[i][i];
}
return ans;
}