BZOJ 1778: [Usaco2010 Hol]Dotp 驱逐猪猡 概率与期望+高斯消元

这个还挺友好的,自己相对轻松能想出来~
令 $f[i]$ 表示起点到点 $i$ 的期望次数,则 $ans[i]=f[i]\times \frac{p}{q}$

#include <cmath>   
#include <cstdio> 
#include <algorithm>  
#define N 305 
#define setIO(s) freopen(s".in","r",stdin) , freopen(s".out","w",stdout) 
using namespace std;  
int edges;  
double f[N][N];       
int deg[N],hd[N],to[N*N],nex[N*N]; 
void add(int u,int v) 
{ 
    nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;  
}
void Gauss(int n)
{
    int i,j,k,now;
    for(i=1;i<=n;++i)
    {
        now=i;        
        for(j=i;j<=n;++j)
        {
            if(fabs(f[j][i])>fabs(f[now][i])) now=j; 
        }
        if(now!=i)
        {
            for(j=1;j<=n;++j) swap(f[i][j],f[now][j]);
        }
        if(f[i][i])
        {
            for(j=i+1;j<=n+1;++j) f[i][j]/=f[i][i];
            f[i][i]=1;
        }
        for(j=i+1;j<=n;++j)
        {
            double div=f[j][i];  
            for(k=i+1;k<=n+1;++k) f[j][k]-=div*f[i][k];                                        
            f[j][i]=0;
        }
    }
    for(i=n;i>=1;--i)
    {
        for(j=i+1;j<=n;++j)
        {
            f[i][n+1]-=f[j][n+1]*f[i][j];  
        }
    }
}        
int main() 
{ 
    // setIO("input"); 
    int n,m,p,q,i,j;   
    double in,out; 
    scanf("%d%d%d%d",&n,&m,&p,&q); 
    in=1.0*(double)(1.0*p/q),out=1.0-in;  
    for(i=1;i<=m;++i) 
    {
        int a,b; 
        scanf("%d%d",&a,&b),add(a,b),add(b,a),++deg[a],++deg[b]; 
    } 
    f[1][n+1]=1;   
    for(i=1;i<=n;++i) 
    {
        f[i][i]=1;   
        for(j=hd[i];j;j=nex[j]) 
        {
            int v=to[j];     
            f[i][v]=-((1.0/deg[v])*out);       
        }   
    } 
    Gauss(n);   
    for(i=1;i<=n;++i) 
    {
        printf("%.9f\n",f[i][n+1]*in); 
    }
    return 0; 
}

  

猜你喜欢

转载自www.cnblogs.com/guangheli/p/11529600.html