首页 > 其他 > 详细

解题:SDOI 2014 重建

时间:2019-02-26 22:32:53      阅读:263      评论:0      收藏:0      [点我收藏+]

题面

做这个这个题需要稍微深入理解一点矩阵树定理:套矩阵树定理得到的东西是有意义的,它是“所有生成树边权乘积之和”(因为度数矩阵是点的边权和,邻接矩阵是边权),即$\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 namespace std;
 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(int j=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 }
View Code

 

解题:SDOI 2014 重建

原文:https://www.cnblogs.com/ydnhaha/p/10440452.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!