解題:SDOI 2014 重建
阿新 • • 發佈:2019-02-27
esp str amp mat algorithm 生成樹 ret div void
題面
做這個這個題需要稍微深入理解一點矩陣樹定理:套矩陣樹定理得到的東西是有意義的,它是“所有生成樹邊權乘積之和”(因為度數矩陣是點的邊權和,鄰接矩陣是邊權),即$\sum_{t}\prod_{e∈t}v_e$,其中t是生成樹集合中的樹。
1 #include<cmath> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define double long double 6 using namespaceView Codestd; 7 const int N=55; 8 const double eps=1e-10; 9 double rd,mul,equ[N][N]; int n; 10 void Correct(double &x) 11 { 12 if(x<=eps) x=eps; 13 if(1-x<=eps) x=1-eps; 14 } 15 void Guass() 16 { 17 for(int i=1;i<=n;i++) 18 { 19 int tmp=i; 20 for(intj=i+1;j<=n;j++) 21 if(fabs(equ[j][i])>fabs(equ[tmp][i])) tmp=j; 22 for(int j=i;j<=n;j++) 23 swap(equ[i][j],equ[tmp][j]); 24 for(int j=1;j<=n;j++) 25 if(i!=j) 26 { 27 double tep=equ[j][i]/equ[i][i];28 for(int k=i;k<=n;k++) 29 equ[j][k]-=tep*equ[i][k]; 30 } 31 } 32 } 33 int main() 34 { 35 scanf("%d",&n),mul=1; 36 for(int i=1;i<=n;i++) 37 for(int j=1;j<=n;j++) 38 { 39 scanf("%Lf",&rd),Correct(rd); 40 if(i<j) mul*=(1-rd); equ[i][j]=rd/(1-rd); 41 } 42 for(int i=1;i<=n;i++) 43 { 44 equ[i][i]=0; 45 for(int j=1;j<=n;j++) 46 if(i!=j) equ[i][i]-=equ[i][j]; 47 } 48 // for(int i=1;i<=n;i++,puts("")) 49 // for(int j=1;j<=n;j++) 50 // printf("%.2Lf ",equ[i][j]); 51 n--,Guass(); 52 for(int i=1;i<=n;i++) mul*=equ[i][i]; 53 printf("%.5Lf",abs(mul)); 54 return 0; 55 }
解題:SDOI 2014 重建