BZOJ 1778: [Usaco2010 Hol]Dotp 驱逐猪猡 概率与期望+高斯消元
这个还挺友好的,自己相对轻松能想出来~
令 $f[i]$ 表示起点到点 $i$ 的期望次数,则 $ans[i]=f[i]\times \frac{p}{q}$
#include <cmath> #include <cstdio> #include <algorithm> #define N 305 #define setIO(s) freopen(s".in","r",stdin) , freopen(s".out","w",stdout) using namespace std; int edges; double f[N][N]; int deg[N],hd[N],to[N*N],nex[N*N]; void add(int u,int v) { nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; } 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,m,p,q,i,j; double in,out; scanf("%d%d%d%d",&n,&m,&p,&q); in=1.0*(double)(1.0*p/q),out=1.0-in; for(i=1;i<=m;++i) { int a,b; scanf("%d%d",&a,&b),add(a,b),add(b,a),++deg[a],++deg[b]; } f[1][n+1]=1; for(i=1;i<=n;++i) { f[i][i]=1; for(j=hd[i];j;j=nex[j]) { int v=to[j]; f[i][v]=-((1.0/deg[v])*out); } } Gauss(n); for(i=1;i<=n;++i) { printf("%.9f\n",f[i][n+1]*in); } return 0; }