BZOJ 3534 重建

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3534

题意:给定一个无向图,每条边有选择概率P;求选出的边恰是一棵生成树的概率。

首先,将A[i][j]从01变成这条边的概率,然后a[i][i]减去每条有i的边的概率,对此求n-1阶主子式的行列式,

可以得到:Σ(p[i]*p[i+1]*p[i+2]*...p[n-1])(p代表某棵树的集合中,这个集合里每条边选中的概率)

可是,这个概率只与树边有关,却无法保证没有非树边

我们重新考虑,令原先加入的a[i][j]变成(a[i][j]/(1-a[i][j])),再令tmp=(1-p[1])*(1-p[2])*...(1-p[m]),然后求行列式,最后选中的树边的因子,都是P[i],不选中的非树边的因子是(1-p[i]),于是问题完美解决。

 1 #include<algorithm>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<iostream>
 6 double a[505][505];
 7 const double eps=1e-10;
 8 int n;
 9 int zero(double x){
10     if (x<-eps) return -1;
11     else return x>eps;
12 }
13 double gauss(){
14     double res=1;
15     for (int i=1;i<=n;i++){
16         int k=i;
17         for (int j=i+1;j<=n;j++) if (fabs(a[j][i])>fabs(a[k][i])) k=j;
18         if (k!=i){
19             for (int j=1;j<=n;j++) std::swap(a[i][j],a[k][j]);
20         }
21         for (int j=i+1;j<=n;j++){
22          double tmp=a[j][i]/a[i][i];
23          for (int k=i;k<=n;k++)
24           a[j][k]-=a[i][k]*tmp;
25         }
26         if (!zero(a[i][i])) return 0;
27     }
28     for (int i=1;i<=n;i++) res*=a[i][i];
29     return std::fabs(res);
30 }
31 int main(){
32     scanf("%d\n",&n);
33     double tm=1;
34     for (int i=1;i<=n;i++)
35         for (int j=1;j<=n;j++){
36             scanf("%lf",&a[i][j]);
37             if (i==j) continue;
38             if (a[i][j]>1-eps) a[i][j]-=eps;
39             if (i<j) tm*=1-a[i][j];
40             a[i][j]/=1-a[i][j];
41         }
42     for (int i=1;i<=n;i++)
43      for (int j=1;j<=n;j++)
44       if (i!=j)
45        a[i][i]-=a[i][j];
46     n--;
47     printf("%.10lf\n",gauss()*tm);
48 }
时间: 2024-11-15 16:54:23

BZOJ 3534 重建的相关文章

BZOJ 3534 [Sdoi2014]重建

题解:矩阵树定理 邻接矩阵-度数矩阵(期望下) 求出来的行列式为所有(生成树边权乘积)的和 每条边边权化为 c/(1-c),最后乘上π(1-c),对1边权特殊处理一下 问题:矩阵树定理不熟,不会证明 #include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; const int maxn=60; const double eps=1e-9

生成树

[BZOJ 3534] 重建 题意 给定一张 n (1 < n <= 50) 个点 m 条边的无向图, 每条边有一定出现的概率, 问出现的边恰好形成一个生成树的概率. 实现 注意到对于出现概率为 1 的边, 分母可能为 0 . 我们对 d = 1 变换为 d = 1-EPS 就好了. 1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cctype>

@算法 - [email&#160;protected] matrix - tree 定理(矩阵树定理)

目录 @0 - 参考资料@ @0.5 - 你所需要了解的线性代数知识@ @1 - 定理主体@ @证明 part - [email protected] @证明 part - [email protected] @证明 part - [email protected] @证明 part - 4@ @2 - 一些简单的推广@ @3 - 例题与应用@ @0 - 参考资料@ MoebiusMeow 的讲解(超喜欢这个博主的!) 网上找的另外一篇讲解 @0.5 - 你所需要了解的线性代数知识@ 什么是矩阵

旧题新做:从idy的视角看数据结构

“今天你不写总结……!!!” 额…… 还是讲我的吧.这些考试都是idy出的题. 20170121:DFS序. ST表.线段树练习 这是第一次考数据结构. Problem 1. setsum 1 second 给你一个长度为N 的整数序列,支持两种操作: • modity l r val 将区间[l,r] 中的所有数修改为val • query l r 询问区间[l,r] 所有数的和 分析:最简单的线段树,区间更改区间求和.但注意是更改,不是添改,sum与flag需同时覆盖. Problem 2.

Matrix_tree Theorem 学习笔记

Matrix_tree Theorem: 给定一个无向图, 定义矩阵A A[i][j] = - (<i, j>之间的边数) A[i][i] = 点i的度数 其生成树的个数等于 A的任意n - 1阶主子式的值. 关于定理的相关证明 可以看这篇文章, 讲得非常详细, 耐心看就能看懂: 关于求行列式, 可以用高斯消元. 如果是模域下求行列式, 可以用欧几里得算法. 具体实现看这篇文章 模域下求行列式 模板题:SPOJ DETER3 代码: 1 #include <cstdio> 2 #i

线性代数 专场 暨 一周年纪念博客

前言 正好今天学习OI一整年,发篇博客纪念纪念. 听说联赛现在全国排名?那完了,一年OI一场空. 记得去年这个时候刚学OI,跟那些初中就开始学的大佬听课,第一节他们就讲2-sat,第二节就是线性代数. 我的内心是 然后,我就自闭了一个月. 如今又来看这些玄学玩意儿. 先列一下知识点(显得我更像是抄课件了呢) 线性基  高斯消元   行列式(主要是矩阵树定理)  矩阵的幂(邻接矩阵.矩阵加速递推) (以后可能会写总结吧,咕,我在) 序 还记得上一个专场是什么吗? 打表找规律,乱搞出奇迹,我对拍了1

bzoj 2957: 楼房重建.

2957: 楼房重建 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2303  Solved: 1088[Submit][Status][Discuss] Description 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些事件发生在一个二维平面上.小A在平面上(0,0)点的位置,第i栋楼房可以用一条连接(i,0)和

【BZOJ 2957】 2957: 楼房重建 (线段树)

2957: 楼房重建 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1753  Solved: 841 Description 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些事件发生在一个二维平面上.小A在平面上(0,0)点的位置,第i栋楼房可以用一条连接(i,0)和(i,Hi)的线段表示,其中Hi为第i栋楼房的高度.

bzoj 2957: 楼房重建 线段树

2957: 楼房重建 Time Limit: 10 Sec  Memory Limit: 256 MB[Submit][Status][Discuss] Description 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些事件发生在一个二维平面上.小A在平面上(0,0)点的位置,第i栋楼房可以用一条连接(i,0)和(i,Hi)的线段表示,其中Hi为第i栋楼房的高度.