【bzoj1778】[Usaco2010 Hol]Dotp 驱逐猪猡 矩阵乘法+概率dp+高斯消元
题目描述
奶牛们建立了一个随机化的臭气炸弹来驱逐猪猡。猪猡的文明包含1到N (2 <= N <= 300)一共N个猪城。这些城市由M (1 <= M <= 44,850)条由两个不同端点A_j和B_j (1 <= A_j<= N; 1 <= B_j <= N)表示的双向道路连接。保证城市1至少连接一个其它的城市。一开始臭气弹会被放在城市1。每个小时(包括第一个小时),它有P/Q (1 <= P <=1,000,000; 1 <= Q <= 1,000,000)的概率污染它所在的城市。如果这个小时内它没有污染它所在的城市,那麽它随机地选择一条道路,在这个小时内沿着这条道路走到一个新的城市。可以离开这个城市的所有道路被选择的概率均等。因为这个臭气弹的随机的性质,奶牛们很困惑哪个城市最有可能被污染。给定一个猪猡文明的地图和臭气弹在每个小时内爆炸的概率。计算每个城市最终被污染的概率。如下例,假设这个猪猡文明有两个连接在一起的城市。臭气炸弹从城市1出发,每到一个城市,它都有1/2的概率爆炸。 1--2 可知下面这些路径是炸弹可能经过的路径(最后一个城市是臭气弹爆炸的城市): 1: 1 2: 1-2 3: 1-2-1 4: 1-2-1-2 5: 1-2-1-2-1 ... 要得到炸弹在城市1终止的概率,我们可以把上面的第1,第3,第5……条路径的概率加起来,(也就是上表奇数编号的路径)。上表中第k条路径的概率正好是(1/2)^k,也就是必须在前k-1个回合离开所在城市(每次的概率为1 - 1/2 = 1/2)并且留在最后一个城市(概率为1/2)。所以在城市1结束的概率可以表示为1/2 + (1/2)^3 + (1/2)^5 + ...。当我们无限地计算把这些项一个个加起来,我们最后会恰好得到2/3,也就是我们要求的概率,大约是0.666666667。这意味着最终停留在城市2的概率为1/3,大约为0.333333333。
输入
* 第1行: 四个由空格隔开的整数: N, M, P, 和 Q * 第2到第M+1行: 第i+1行用两个由空格隔开的整数A_j和B_j表示一条道路。
输出
* 第1到第N行: 在第i行,用一个浮点数输出城市i被摧毁的概率。误差不超过10^-6的答桉会 被接受(注意这就是说你需要至少输出6位有效数字使得答桉有效)。
样例输入
2 1 1 2
1 2
样例输出
0.666666667
0.333333333
题解
矩阵乘法+概率dp+高斯消元
%PoPoQQQ,大爷就是强啊
设S为初始炸弹出现在每个位置的概率,那么显然S=[1,0,0,...,0]
设T为炸弹移动的矩阵,T[i][j]表示从i不爆炸且移动到j的概率,那么如果i到j有边,则T[i][j]=(1-p/q)/d[i],否则T[i][j]=0,易知T[i][j]<1-p/q。
根据定义,很容易得知(T*T)[i][j]<(1-p/q)^2,(T*T*T)[i][j]<(1-p/q)^3,...,$T^\infty$[i][j]<$(1-p/q)^\infty$=0。
而炸弹在第1s内爆炸的概率为$\frac pqS$,第2s内爆炸的概率为$\frac pqST$,第3s内爆炸的概率为$\frac pqST^2$,...
故答案ANS(炸弹在每个位置爆炸的概率)有如下关系:

其中,I表示单位矩阵,第一个式子使用了等比数列求和公式,而第二个式子将已知矩阵I-T乘到左端。
然后我们可以发现I-T、p/q*S都是已知矩阵,只有ANS未知,并且ANS是一个1*n的矩阵,只有n个未知数。
所以我们可以设这些未知数分别为x1、x2、...、xn,然后根据已知条件列出方程,使用高斯消元求解。
#include <cstdio>
#include <cmath>
#include <algorithm>
#define N 310
#define M 90010
using namespace std;
int x[M] , y[M] , d[N] , n;
double a[N][N];
void gauss()
{
int i , j , k;
double t;
for(i = 1 ; i <= n ; i ++ )
{
for(k = 0 , j = i ; j <= n ; j ++ )
if(fabs(a[j][i]) > fabs(a[k][i]))
k = j;
for(j = i ; j <= n + 1 ; j ++ ) swap(a[i][j] , a[k][j]);
for(j = i + 1 ; j <= n ; j ++ )
for(t = a[j][i] / a[i][i] , k = i ; k <= n + 1 ; k ++ )
a[j][k] -= t * a[i][k];
}
for(i = n ; i >= 1 ; i -- )
{
for(j = i + 1 ; j <= n ; j ++ ) a[i][n + 1] -= a[i][j] * a[j][n + 1];
a[i][n + 1] /= a[i][i];
}
}
int main()
{
int m , p , q , i;
scanf("%d%d%d%d" , &n , &m , &p , &q);
for(i = 1 ; i <= m ; i ++ ) scanf("%d%d" , &x[i] , &y[i]) , d[x[i]] ++ , d[y[i]] ++ ;
for(i = 1 ; i <= m ; i ++ ) a[x[i]][y[i]] = ((double)p / q - 1) / d[y[i]] , a[y[i]][x[i]] = ((double)p / q - 1) / d[x[i]];
for(i = 1 ; i <= n ; i ++ ) a[i][i] = 1;
a[1][n + 1] = (double)p / q;
gauss();
for(i = 1 ; i <= n ; i ++ ) printf("%.9lf\n" , a[i][n + 1]);
return 0;
}
【bzoj1778】[Usaco2010 Hol]Dotp 驱逐猪猡 矩阵乘法+概率dp+高斯消元的更多相关文章
- BZOJ1778 [Usaco2010 Hol]Dotp 驱逐猪猡
首先我们列出转移矩阵$M$,$M_{i, j} = \frac {1 - \frac{p} {q}} {deg[i]}$(i,j之间有边)or $M_{i, j} = 0$(i,j之间没边) 则这个矩 ...
- bzoj1778: [Usaco2010 Hol]Dotp 驱逐猪猡(概率DP+高斯消元)
深夜肝题...有害身心健康QAQ 设f[i]为到达i的概率,d[i]为i的度数. 因为无限久之后炸弹爆炸的概率是1,所以最后在i点爆炸的概率实际上就是f[i]/sigma(f[]) 列出方程组 f[i ...
- 【BZOJ1778】[Usaco2010 Hol]Dotp 驱逐猪猡 期望DP+高斯消元
[BZOJ1778][Usaco2010 Hol]Dotp 驱逐猪猡 Description 奶牛们建立了一个随机化的臭气炸弹来驱逐猪猡.猪猡的文明包含1到N (2 <= N <= 300 ...
- BZOJ 1778: [Usaco2010 Hol]Dotp 驱逐猪猡 [高斯消元 概率DP]
1778: [Usaco2010 Hol]Dotp 驱逐猪猡 题意:一个炸弹从1出发p/q的概率爆炸,否则等概率走向相邻的点.求在每个点爆炸的概率 高斯消元求不爆炸到达每个点的概率,然后在一个点爆炸就 ...
- BZOJ_1778_[Usaco2010 Hol]Dotp 驱逐猪猡_概率DP+高斯消元
BZOJ_1778_[Usaco2010 Hol]Dotp 驱逐猪猡_概率DP+高斯消元 题意: 奶牛们建立了一个随机化的臭气炸弹来驱逐猪猡.猪猡的文明包含1到N (2 <= N <= 3 ...
- BZOJ 1778: [Usaco2010 Hol]Dotp 驱逐猪猡
1778: [Usaco2010 Hol]Dotp 驱逐猪猡 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 563 Solved: 216[Submi ...
- 【BZOJ1778】[Usaco2010 Hol]Dotp 驱逐猪猡
题解: 网上有一种复杂的方法..好像复杂度并没有优势就没看 定义f[i]表示i的期望经过次数,f[i]=sigma{f[j]*p/q/du[j]}+(i==1); 然后高斯消元就可以了 最后求出来的f ...
- bzoj 1778 [Usaco2010 Hol]Dotp 驱逐猪猡(高斯消元)
[题意] 炸弹从1开始运动,每次有P/Q的概率爆炸,否则等概率沿边移动,问在每个城市爆炸的概率. [思路] 设M表示移动一次后i->j的概率.Mk为移动k次后的概率,则有: Mk=M^k 设S= ...
- 【BZOJ】1778: [Usaco2010 Hol]Dotp 驱逐猪猡
[题意]给定无向图,炸弹开始在1,在每个点爆炸概率Q=p/q,不爆炸则等概率往邻点走,求在每个点爆炸的概率.n<=300. [算法]概率+高斯消元 [题解]很直接的会考虑假设每个点爆炸的概率,无 ...
随机推荐
- 洛谷 P1588 丢失的牛
题目描述 FJ丢失了他的一头牛,他决定追回他的牛.已知FJ和牛在一条直线上,初始位置分别为x和y,假定牛在原地不动.FJ的行走方式很特别:他每一次可以前进一步.后退一步或者直接走到2*x的位置.计算他 ...
- 2002-2003 ACM-ICPC Northeastern European Regional Contest (NEERC 02) A Amusing Numbers (数学)
其实挺简单的.先直接算出之前已经排在k这个数前面的数字.比如543是三位的,那么100~543都是可以的,两位的10~54. 如果还需要往前面补的话,那么依次考虑1000~5430,5430是上界不能 ...
- Android(java)学习笔记124:利用Service在后台播放背景音乐
1. 在android应用程序里,有一种没有UI的类(android.app.Service)——Service.简单来说,Service是一个 background process(背景程序),通过 ...
- C#数组简介
一.数组的定义 数组:是一种包含若干个变量的数据结构,这些变量可以通过索引进行访问. 数组的元素:数组中的变量就称为数组的元素. 元素类型:数组中的元素具有相同的数据类型,该数据类型就称为数组的元素类 ...
- Java第11次作业:什么是继承?继承的好处?什么是覆写?super()?构造代码块?子父类初始化顺序? 抽象类能用final声明吗?final关键字声明类 方法 变量以及全局常量?抽象类的构造方法?
什么是继承? 继承是以父类为基础,子类可以增加新的数据或新的功能.子类不能选择性地继承父类.这种技术使得复用以前的代码非常容易. JAVA不支持多继承,单继承使JAVA的继承关系很简单,一个类只能有一 ...
- Java中什么是匿名对象,空参构造方法输出创建了几个匿名对象,属性声明成static
package com.swift; //使用无参构造方法自动生成对象,序号不断自增 public class Person { private static int count; //如果在定义类时 ...
- 53. Maximum Subarray@python
Given an integer array nums, find the contiguous subarray (containing at least one number) which has ...
- nodejs 静态资源服务与接口代理跨域
首先需要 npm install express 和 npm install request 代码如下: const express = require('express'); const path ...
- Optimization & Map
- opencv和numpy的安装
近日,学姐让我们切割图片,查了一下资料,发现我需要安装opencv和numpy.但是在安装过程中却出现了很多小问题,我在此结合自和自己的安装经验和网上查找的资料,做一个笔记. 1.opencv的安装 ...