• BZOJ 3270: 博物馆 概率与期望+高斯消元


    和游走挺像的,都是将概率转成期望出现的次数,然后拿高斯消元来解. 

    #include <bits/stdc++.h>  
    #define N 23
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std;   
    double in[N],out[N],f[N*N][N*N];   
    int G[N][N],deg[N],idx[N][N],tot; 
    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,i,j,m,A,B; 
        scanf("%d%d%d%d",&n,&m,&A,&B);    
        for(i=1;i<=m;++i) 
        {
            int u,v; 
            scanf("%d%d",&u,&v),G[u][v]=G[v][u]=1,++deg[u],++deg[v]; 
        }    
        for(i=1;i<=n;++i) scanf("%lf",&in[i]), out[i]=(1-in[i])/(1.0*deg[i]);    
        for(i=1;i<=n;++i) G[i][i]=1;  
        for(i=1;i<=n;++i) 
        {
            for(j=1;j<=n;++j) idx[i][j]=++tot;  
        } 
        f[idx[A][B]][tot+1]=-1;       
        for(i=1;i<=n;++i) 
        {
            for(j=1;j<=n;++j) 
            {
                int cur=idx[i][j];  
                f[cur][cur]=-1;   
                for(int x=1;x<=n;++x) 
                {
                    for(int y=1;y<=n;++y) 
                    {
                        if(x==y||!G[i][x]||!G[j][y]) continue;     
                        int id=idx[x][y];    
                        if(i==x&&j==y) 
                        {
                            f[cur][id]+=in[i]*in[j];   
                        }
                        else if(i==x&&j!=y) 
                        { 
                            f[cur][id]+=in[x]*out[y];     
                        }
                        else if(i!=x&&j==y) 
                        { 
                            f[cur][id]+=out[x]*in[y];  
                        }
                        else 
                        { 
                            f[cur][id]+=out[x]*out[y];   
                        }
                    }
                }
            }
        }
        Gauss(tot);   
        for(i=1;i<=n;++i) 
        { 
            printf("%.6f ",f[idx[i][i]][tot+1]);   
        }
        return 0; 
    }
    

      

  • 相关阅读:
    常用的一些js方法
    git常用命令
    thread join和detach的区别
    C和C++的区别和联系
    C++面试集锦( 面试被问到的问题 )
    C/C++面试题:编写类String的构造函数、析构函数和赋值函数。
    C++ 多态的实现及原理
    获取当前操作系统的ip
    CString的头文件
    C++ 多用户模式下同一个exe只能运行一次
  • 原文地址:https://www.cnblogs.com/guangheli/p/11528951.html
Copyright © 2020-2023  润新知