BZOJ1778: [Usaco2010 Hol]Dotp 驱逐猪猡

Posted ONION_CYC

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ1778: [Usaco2010 Hol]Dotp 驱逐猪猡相关的知识,希望对你有一定的参考价值。

【题意】给定无向图,炸弹开始在1,在每个点爆炸概率p/q,不爆炸则等概率往邻点走,求在每个点爆炸的概率。

【算法】数学概率期望+高斯消元

【题解】令f[i]表示炸弹到达i点的概率(之前不爆炸)。

f[i]=∑f[j]*(1-Q)/d[j]

特别的,f[1]=∑f[j]*(1-Q)/d[j]+1(一开始就到达)。

只要一个点到就是到达,故使用概率加法。

使用高斯消元求解方程组,最后ansi=f[i]*Q

另一种思路,由于炸弹最终爆炸概率为1,所以sum=∑f[i],ansi=f[i]/sum

此题还有另一种解法,计算每个点到达次数的期望,到达概率和到达次数正相关(注意方程步数+1)。

技术分享
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=310,maxm=50010;
struct edge{int v,from;}e[maxm*2];
int first[maxn],tot,d[maxn],n,m,p,q;
double f[maxn][maxn];

void insert(int u,int v){tot++;e[tot].v=v;e[tot].from=first[u];first[u]=tot;d[v]++;}
void gauss(){
    for(int i=1;i<=n;i++){
        int t=i;
        for(int j=i+1;j<=n;j++)if(f[j][i]>f[t][i])t=j;
        if(t!=i)for(int j=i+1;j<=n;j++)swap(f[i][j],f[t][j]);
        for(int j=i+1;j<=n;j++)
            for(int k=n+1;k>=i;k--)
                f[j][k]-=f[j][i]/f[i][i]*f[i][k];
    }
    for(int i=n;i>=1;i--){
        for(int j=i+1;j<=n;j++)f[i][n+1]-=f[i][j]*f[j][n+1];
        f[i][n+1]/=f[i][i];
    }
}
int main(){
    scanf("%d%d%d%d",&n,&m,&p,&q);double Q=1.0*p/q;
    int u,v;
    for(int i=1;i<=m;i++){
        scanf("%d%d",&u,&v);
        insert(u,v);insert(v,u);
    }
    f[1][n+1]=1;
    for(int k=1;k<=n;k++){
        f[k][k]=1;
        for(int i=first[k];i;i=e[i].from)f[k][e[i].v]=-(1-Q)/d[e[i].v];
    }
    gauss();
    for(int i=1;i<=n;i++)printf("%.9lf\n",f[i][n+1]*Q);
    return 0;
}
View Code

 

以上是关于BZOJ1778: [Usaco2010 Hol]Dotp 驱逐猪猡的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ_1778_[Usaco2010 Hol]Dotp 驱逐猪猡_概率DP+高斯消元

BZOJ1778: [Usaco2010 Hol]Dotp 驱逐猪猡

BZOJ1778: [Usaco2010 Hol]Dotp 驱逐猪猡

bzoj1778[Usaco2010 Hol]Dotp 驱逐猪猡 矩阵乘法+概率dp+高斯消元

[Luogu P2973&BZOJ 1778][USACO10HOL]赶小猪DOtP(高斯消元+期望)

bzoj1776[Usaco2010 Hol]cowpol 奶牛政坛*