博物馆 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; } }