zoukankan      html  css  js  c++  java
  • bzoj3534 [Sdoi2014]重建

    Description

      T国有N个城市,用若干双向道路连接。一对城市之间至多存在一条道路。
        在一次洪水之后,一些道路受损无法通行。虽然已经有人开始调查道路的损毁情况,但直到现在几乎没有消息传回。
        辛运的是,此前T国政府调查过每条道路的强度,现在他们希望只利用这些信息估计灾情。具体地,给定每条道路在洪水后仍能通行的概率,请计算仍能通行的道路恰有N-1条,且能联通所有城市的概率。

    Input

      输入的第一行包含整数N。
      接下来N行,每行N个实数,第i+l行,列的数G[i][j]表示城市i与j之
    间仍有道路联通的概率。
        输入保证G[i][j]=G[j][i],且G[i][j]=0;G[i][j]至多包含两位小数。

    Output

        输出一个任意位数的实数表示答案。
        你的答案与标准答案相对误差不超过10^(-4)即视为正确。

    Sample Input

    3
    0 0.5 0.5
    0.5 0 0.5
    0.5 0.5 0

    Sample Output

    0.375

    HINT

    1 < N < =50

    数据保证答案非零时,答案不小于10^-4

    正解:矩阵树定理。

    首先矩阵树定理的度数矩阵记录的是每个点的边权和,邻接矩阵记录的是边权,求的则是所有生成树的边权乘积和。

    我们可以发现,一棵生成树的概率就是所有存在的边的存在概率乘不存在的边的不存在概率。

    $(i,j)$的概率是$p(i,j)$,那么把$frac{p(i,j)}{1-p(i,j)}$当成边权,最后再乘上所有的$1-p(i,j)$即可。

     1 #include <bits/stdc++.h>
     2 #define il inline
     3 #define RG register
     4 #define ll long long
     5 #define eps (1e-9)
     6 
     7 using namespace std;
     8 
     9 double g[55][55],ans;
    10 int n;
    11 
    12 il void gauss(){
    13   for (RG int i=1,id;i<n;++i){
    14     for (id=i;id<n;++id) if (fabs(g[id][i])>eps) break;
    15     if (id!=i) for (RG int j=1;j<n;++j) swap(g[i][j],g[id][j]);
    16     RG double tmp=g[i][i],ret;
    17     for (RG int j=i+1;j<n;++j){
    18       if (fabs(g[j][i])<eps) continue; ret=g[j][i]/tmp;
    19       for (RG int k=i;k<n;++k) g[j][k]-=g[i][k]*ret;
    20     }
    21     ans*=g[i][i];
    22   }
    23   ans=fabs(ans); return;
    24 }
    25 
    26 int main(){
    27 #ifndef ONLINE_JUDGE
    28   freopen("rebuild.in","r",stdin);
    29   freopen("rebuild.out","w",stdout);
    30 #endif
    31   cin>>n,ans=1;
    32   for (RG int i=1;i<=n;++i)
    33     for (RG int j=1;j<=n;++j){
    34       scanf("%lf",&g[i][j]);
    35       RG double tmp=fabs(1-g[i][j])>eps?(1-g[i][j]):eps;
    36       if (i<j) ans*=tmp; g[i][j]/=tmp;
    37     }
    38   for (RG int i=1;i<=n;++i)
    39     for (RG int j=1;j<=n;++j)
    40       if (i!=j) g[i][i]-=g[i][j];
    41   gauss(),printf("%0.9lf
    ",ans); return 0;
    42 }
  • 相关阅读:
    jqGrid api 中文说明
    jsp + js + 前端弹出框
    js中关于带数字类型参数传参丢失首位数字0问题
    java中WGS84坐标(ios)转换BD-09坐标(百度坐标)
    Java中的“浅复制”与“深复制”
    Git错误:error:failed to push some refs to 'git@gitee.com:name/project.git'
    git操作教程
    线程调度及进程调度
    同步锁Lock
    多线程案例
  • 原文地址:https://www.cnblogs.com/wfj2048/p/8378239.html
Copyright © 2011-2022 走看看