「SDOI2014」重建

题意

给一个图\(G\),两点\((u,v)\)有边的概率是\(p_{u,v}\),求有\(n-1\)条边通行且组成了一颗树的概率是多少。


抄了几个矩阵树定理有趣的感性说法

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

  • 考虑Kirchhoff矩阵的意义:\(K[G]=D[G]−A[G]=B[G]B^T[G]\),之所以能够进行生成树计数是对于其伴随矩阵在计数\(n−1\)条边的集合时,当\(n−1\)条边中存在环就会产生线性组合而导致行列式为零,否则恰好对角线上均为伴随矩阵中所赋的值,使得\(\det(B_{i,j})^2\)就为\(1\)

考虑直接把度数矩阵赋为出度概率和,连边矩阵为概率,然后相减套矩阵树定理求得是什么

\[\sum_T\prod_{(u,v)\in T}p_{u,v}
\]

然而我们需要求

\[\sum_T\prod_{(u,v)\in T}p_{u,v}\prod_{(u,v)\notin T}(1-p_{u,v})
\]

化一下可以得到

\[\prod_{(u,v)\in G}(1-p_{u,v})\sum_T\prod_{(u,v)\in T}\frac{p_{u,v}}{1-p_{u,v}}
\]

然后把后面的拿去跑矩阵树就可以了。

注意一些精度问题,把\(p=0\)搞成\(p=\epsilon\),\(p=1\)搞成\(1-\epsilon\)差不多就可以了


Code:

#include <cstdio>
#include <cmath>
#include <algorithm>
const int N=52;
const double eps=1e-10;
int n;
double p[N][N],a[N][N];
void Gauss()
{
--n;
for(int i=1;i<=n;i++)
{
int id=i;
for(int j=i+1;j<=n;j++)
if(fabs(a[id][i])<fabs(a[j][i])) id=j;
std::swap(a[id],a[i]);
for(int j=i+1;j<=n;j++)
{
double p=a[j][i]/a[i][i];
for(int k=n;k>=i;k--)
a[j][k]-=a[i][k]*p;
}
}
}
int main()
{
scanf("%d",&n);
double sum=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
scanf("%lf",&p[i][j]);
if(p[i][j]==0) p[i][j]=eps;
if(p[i][j]==1) p[i][j]=1-eps;
if(i<j) sum*=1-p[i][j];
a[i][j]=p[i][j]/(1-p[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];
}
Gauss();
for(int i=1;i<=n;i++) sum*=fabs(a[i][i]);
printf("%.4lf\n",sum);
return 0;
}

2019.2.21

「SDOI2014」重建 解题报告的更多相关文章

  1. 「SDOI2014」Lis 解题报告

    「SDOI2014」Lis 题目描述 给定序列 \(A\),序列中的每一项 \(A_i\) 有删除代价 \(B_i\) 和附加属性 \(C_i\). 请删除若干项,使得 \(A\) 的最长上升子序列长 ...

  2. 「ZJOI2016」旅行者 解题报告

    「ZJOI2016」旅行者 对网格图进行分治. 每次从中间选一列,然后枚举每个这一列的格子作为起点跑最短路,进入子矩形时把询问划分一下,有点类似整体二分 至于复杂度么,我不会阿 Code: #incl ...

  3. 「HNOI2016」树 解题报告

    「HNOI2016」树 事毒瘤题... 我一开始以为每次把大树的子树再接给大树,然后死活不知道咋做,心想怕不是个神仙题哦 然后看题解后才发现是把模板树的子树给大树,虽然思维上难度没啥了,但是还是很难写 ...

  4. 「HNOI2016」序列 解题报告

    「HNOI2016」序列 有一些高妙的做法,懒得看 考虑莫队,考虑莫队咋移动区间 然后你在区间内部找一个最小值的位置,假设现在从右边加 最小值左边区间显然可以\(O(1)\),最小值右边的区间是断掉的 ...

  5. 「HNOI2016」网络 解题报告

    「HNOI2016」网络 我有一个绝妙的可持久化树套树思路,可惜的是,它的空间是\(n\log^2 n\)的... 注意到对一个询问,我们可以二分答案 然后统计经过这个点大于当前答案的路径条数,如果这 ...

  6. 「HAOI2018」染色 解题报告

    「HAOI2018」染色 是个套路题.. 考虑容斥 则恰好为\(k\)个颜色恰好为\(c\)次的贡献为 \[ \binom{m}{k}\sum_{i\ge k}(-1)^{i-k}\binom{m-k ...

  7. 「HNOI2016」最小公倍数 解题报告

    「HNOI2016」最小公倍数 考虑暴力,对每个询问,处理出\(\le a,\le b\)的与询问点在一起的联通块,然后判断是否是一个联通块,且联通块\(a,b\)最大值是否满足要求. 然后很显然需要 ...

  8. 「SCOI2016」围棋 解题报告

    「SCOI2016」围棋 打CF后困不拉基的,搞了一上午... 考虑直接状压棋子,然后发现会t 考虑我们需要上一行的状态本质上是某个位置为末尾是否可以匹配第一行的串 于是状态可以\(2^m\)压住了, ...

  9. 「SCOI2016」妖怪 解题报告

    「SCOI2016」妖怪 玄妙...盲猜一个结论,然后过了,事后一证,然后假了,数据真水 首先要最小化 \[ \max_{i=1}^n (1+k)x_i+(1+\frac{1}{k})y_i \] \ ...

随机推荐

  1. 软件工程(FZU2015) 赛季得分榜,第三回合

    SE_FZU目录:1 2 3 4 5 6 7 8 9 10 11 12 13 积分规则 积分制: 作业为10分制,练习为3分制:alpha30分: 团队项目分=团队得分+个人贡献分 个人贡献分: 个人 ...

  2. Oracle 表空间不足引起的问题及解决方法

    -- 1 向数据库导入数据时报了ORA-01653: unable to extend table错误,网上查了下原因是由于表空间不足引起的: 查询表空间使用情况语句 select a.tablesp ...

  3. Notepad++的一个用法 转换为unix 格式的文件

    1. 跟昨天的linux 下面无法执行脚本的blog 一样 今天发现 notepad++ 有一个功能如下图: 双击 就能够选择文件的类型.. 转换为 unix 格式 就可以 在linux 下面执行了. ...

  4. Latex常用软件

    Linux texMaker sudo apt-get install texlive-full sudo apt-get install texmaker

  5. C# Note11:如何优雅地退出WPF应用程序

    前言 I should know how I am supposed to exit my application when the user clicks on the Exit menu item ...

  6. AssemblyScript的测试

    详细文档介绍 export function f(x: i32): i32 { if (x === 1 || x === 2) { return 1; } return f(x - 1) + f(x ...

  7. class面向对象-1

    一.基本定义 class cl(object): def __init(self,var) self.var=var def func(self,i) print('%s is in %s'%(i,s ...

  8. java学习之—链表(1)

    /** * 单链表操作 * Create by Administrator * 2018/6/14 0014 * 下午 2:05 **/ public class Link { public int ...

  9. Spring拦截器(学习笔记)

    SpringMVC 中的Interceptor 拦截请求是通过HandlerInterceptor 来实现的 在SpringMVC 中定义一个Interceptor 非常简单,主要有两种方式 第一种方 ...

  10. initial

    摘自http://blog.csdn.net/liming0931/article/details/7039680 首先说说结构化过程语句,在verilog中有两种结构化的过程语句:initial语句 ...