和游走挺像的,都是将概率转成期望出现的次数,然后拿高斯消元来解.
#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; }