題目:
題解:
矩陣樹定理,先前只知道構造方法和基本的求生成樹個數
然而實際上K矩陣是這麼個玩意
我們可以發現其實是跟邊權有關的
其實矩陣樹定理求的是
然後這個題目讓我們求的顯然是
這個式子求的前半截是一樣的,後半截不太一樣,但是顯然
然後就可以帶進去了
然後我們就可以讓a的權值爲後面的一堆就好啦
還有就是當矩陣中出現 時就 當矩陣中出現 時就
BZOJ上的輸出一定要開到1e-10才能過= =
代碼:
#include <cstdio>
#include <cmath>
#include <iostream>
using namespace std;
const int N=55;
const double eps=1e-8;
double a[N][N];
double gauss(int n)
{
double ans=1;
for (int i=1;i<=n;i++)
{
int num=i;
for (int j=i+1;j<=n;j++)
if (abs(a[num][i])<abs(a[j][i])) num=j;
if (num!=i) for (int j=i;j<=n;j++) swap(a[num][j],a[i][j]);
for (int j=i+1;j<=n;j++)
{
double t=a[j][i]/a[i][i];
for (int k=i;k<=n;k++) a[j][k]-=t*a[i][k];
}
if (abs(a[i][i])<eps) return 0;
ans=ans*a[i][i];
}
return abs(ans);
}
int main()
{
int n;scanf("%d",&n);
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
scanf("%lf",&a[i][j]);
double tmp=1;
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
{
if (abs(a[i][j])<eps) a[i][j]=eps;
else if (abs(1.0-a[i][j])<eps) a[i][j]=1.0-eps;
if (i<j) tmp*=1.0-a[i][j];
a[i][j]=a[i][j]/(1.0-a[i][j]);
}
for (int i=1;i<=n;i++)
{
a[i][i]=0;
for (int j=1;j<=n;j++)
if (i!=j) a[i][i]+=a[i][j],a[i][j]=-a[i][j];
}
printf("%.10lf",tmp*gauss(n-1));
}