博物馆 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;
    }
}
原文地址:https://www.cnblogs.com/FOXYY/p/7241964.html