BZOJ 3143: [Hnoi2013]游走
题解:
高斯消元解期望方程
每条边算贡献
用边算不好算
算f(x)表示到x点的次数
f(x)=sigma(f(y))/size+1
对于1和n特判一下
然后n个方程n个未知数
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; const int maxn=509; const double eps=1e-9; double douabs(double x){ if(x<0)return -x; else return x; } int dcmp(double x){ if(douabs(x)<eps)return 0; if(x<0)return -1; else return 1; } int n,m; double E=0; int deg[maxn]={0}; int rx[maxn*maxn],ry[maxn*maxn]; int cntedge=0; int head[maxn]={0}; int to[maxn*maxn],nex[maxn*maxn]; void Addedge(int x,int y){ nex[++cntedge]=head[x]; to[cntedge]=y; head[x]=cntedge; } double a[maxn][maxn]; double ans[maxn]; void Guas(){ for(int j=1;j<=n;++j){ int maxline=j; for(int i=j+1;i<=n;++i){ if(a[i][j]>a[maxline][j])maxline=i; } if(maxline!=j){ for(int i=j;i<=n+1;++i)swap(a[j][i],a[maxline][i]); } for(int i=j+1;i<=n;++i){ double t=a[i][j]/a[j][j]; for(int k=j;k<=n+1;++k)a[i][k]=a[i][k]-t*a[j][k]; } } for(int i=n;i>=1;--i){ for(int j=i+1;j<=n;++j){ a[i][n+1]-=ans[j]*a[i][j]; } ans[i]=a[i][n+1]/a[i][i]; } } priority_queue<double>q; int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=m;++i){ scanf("%d%d",&rx[i],&ry[i]); Addedge(rx[i],ry[i]); Addedge(ry[i],rx[i]); deg[rx[i]]++;deg[ry[i]]++; } for(int u=1;u<=n;++u){ a[u][u]=-1; for(int i=head[u];i;i=nex[i]){ int v=to[i]; if(v==n)continue; a[u][v]=1.0/deg[v]; } } a[1][n+1]=-1; Guas(); ans[n]=0; for(int i=1;i<=m;++i){ int x=rx[i]; int y=ry[i]; q.push(ans[x]/deg[x]+ans[y]/deg[y]); } for(int i=1;i<=m;++i){ double x=q.top();q.pop(); E+=x*i; } printf("%.3f\n",E); return 0; }
致歉:笔者已经意识到这是一篇几乎没有价值的文章,给您的阅读带来不好的体验,并且干扰了您的搜索环境,非常抱歉!