Description
一个无向连通图,顶点从1编号到N,边从1编号到M。
小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分数。当小Z 到达N号顶点时游走结束,总分为所有获得的分数之和。 现在,请你对这M条边进行编号,使得小Z获得的总分的期望值最小。Solution
对于点u(u≠1):到达u的概率 f[u]=∑f[v]/d[v] (Edges(u,v))
而f[1]=∑f[v]/d[v]+1 (Edges(1,v))
高斯消元可以求出所有点的概率
对于每条边 到达边i的概率 p[i]=f[u]/d[u]+f[v]/d[v]
贪心的编号然后求出期望就好了
好像BZOJ上的数据会比较水,洛谷数据…卡精度
#include#include #include #include #include #include #define eps 1e-7using namespace std;int n,m,head[505],cnt=0,d[505];double a[505][505],f[505],p[250005];struct Node{ int next,from,to;}Edges[500005];void addedge(int u,int v){ Edges[++cnt].next=head[u]; head[u]=cnt; Edges[cnt].from=u; Edges[cnt].to=v;}void Gauss(){ for(int i=1;i<=n;i++) { int maxline=i; for(int j=i+1;j<=n;j++) if(a[j][i]>a[maxline][i])maxline=j; if(maxline!=i) for(int j=i;j<=n+1;j++) swap(a[maxline][j],a[i][j]); for(int j=i+1;j<=n;j++) { if(fabs(a[j][i]) 0;i--) { for(int j=n;j>i;j--) a[i][n+1]-=f[j]*a[i][j]; f[i]=a[i][n+1]/a[i][i]; }}int main(){ memset(head,-1,sizeof(head)); scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); addedge(u,v); addedge(v,u); d[u]++,d[v]++; } for(int i=1;i >1]+=(double)f[u]/d[u]; p[(i+1)>>1]+=(double)f[v]/d[v]; } sort(p+1,p+1+m); double ans=0; for(int i=1;i<=m;i++) ans+=p[i]*(m-i+1); printf("%.3lf\n",ans); return 0;}
被卡精度)