zoukankan      html  css  js  c++  java
  • 博物馆 bzoj3270

         首先最难想的是两个人要在同一时间,同一地点相遇,这样很难处理,所以用类似于聪聪和可可的方法,用f[i][j]表示A在i位置,B在j位置,那么f[i][j]的转移方法就有四个

    1、两个人都在原地没动,则a[f[i][j]]+=a[f[i][j]]*p[i]*p[j];

    2(3)、其中有一个人动,以A动为例 a[f[i][j]]+=p[j]*((1-p[v]).chu[v])*a[f[v][j]];

    4、两人都动,类比2即可.

    注意到f是一个矩阵,所以将其编号,之后用高斯消元,接触每一个f[i][i]的值,就是答案;

    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    struct Node{
        int u,v,nxt;
    }g[400];
    int n,m,A,B;
    int chu[25];
    int adj[400],e;
    int f[21][21];
    double p[25];
    double a[410][410];
    double ans[410];
    void add(int u,int v){
        g[++e].v=v; g[e].u=u;
        g[e].nxt=adj[u]; adj[u]=e;
    }
    void gs(){
        int N=n*n+1;
        int T=n*n;
        int h=1,num;
        for(int i=1;i<T;i++,h++){
            num=h;
            for(int j=h+1;j<=T;j++){
                if(fabs(a[j][i]) > fabs(a[num][i])) num=j;
            }
            if(num!=h){
                for(int j=i;j<=N;j++){
                    swap(a[h][j],a[num][j]);    
                }
            }
            if(a[h][i]==0){
                h--;
                continue;
            }
            double ti;
            for(int j=h+1;j<=T;j++){
                if(a[j][i]==0) continue;
                ti=a[j][i]/a[h][i];
                for(int k=i;k<=N;k++){
                    a[j][k]-=a[h][k]*ti;
                }
            }
        }
        for(int i=T;i>=1;i--){
            for(int j=i+1;j<=T;j++){
                a[i][N]-=a[i][j]*ans[j];
            }
            ans[i]=a[i][N]/a[i][i];
        }
         
    }
    void ot();
    int main(){
        //freopen("a.in","r",stdin);
        scanf("%d%d%d%d",&n,&m,&A,&B);
        int x,y;
        for(int i=1;i<=m;i++){
            scanf("%d%d",&x,&y);
            add(x,y); add(y,x);
            chu[x]++; chu[y]++;
        }
        for(int i=1;i<=n;i++){
            add(i,i);
            scanf("%lf",&p[i]);
        }
        memset(a,0,sizeof(a));
        int v1,v2;
        int R;
        a[(A-1)*n+B][n*n+1]=-1;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                R=(i-1)*n+j;
                a[R][R]=-1;
                for(int k=adj[i];k;k=g[k].nxt){
                    v1=g[k].v;
                    for(int h=adj[j];h;h=g[h].nxt){
                        v2=g[h].v;
                        if(v1==v2) continue;
                        if(v1==i && v2==j){
                            a[R][(i-1)*n+j]+=p[i]*p[j]; 
                        }
                        else if(v1==i && v2!=j){
                            a[R][(v1-1)*n+v2]+=p[v1]*((1-p[v2])/chu[v2]);
                        }
                        else if(v1!=i && v2==j){
                            a[R][(v1-1)*n+v2]+=p[v2]*((1-p[v1])/chu[v1]);
                        }
                        else if(v1!=i && v2!=j){
                            a[R][(v1-1)*n+v2]+=((1-p[v1])/chu[v1])*((1-p[v2])/chu[v2]);
                        }
                    }
                }
            }
        }
        //ot();
        gs();
        for(int i=1;i<=n;i++){
            R=(i-1)*n+i;
        //  cout<<"R== "<<"  "<<R<<endl;
            printf("%.6lf ",ans[R]);
        }
        return 0;
    }
    void ot(){
        for(int i=1;i<=n*n;i++){
            for(int j=1;j<=n*n+1;j++){
                cout<<a[i][j]<<"  ";
            }
            cout<<endl;
        }
    }
  • 相关阅读:
    了解HTTP Header之User-Agent和HTTP协议的响应码
    怎样才算一个优秀的管理者
    ldpi、mdpi、hdpi、xhdpi、xxhdpi (无内容,待填)
    手把手教做小偷采集
    java中碰到无法解决的问题:无法访问类的getter访问器
    简单的加密解密处理
    Java中处理二进制移位
    Java中实现String.padLeft和String.padRight
    这短短几行代码价值一万
    从一篇文章中检查特定单词出现数量和第一次出现位置
  • 原文地址:https://www.cnblogs.com/FOXYY/p/7241964.html
Copyright © 2011-2022 走看看