首页 > 代码库 > 数学(概率):HNOI2013 游走
数学(概率):HNOI2013 游走
【题目描述】
一个无向连通图,顶点从1编号到N,边从1编号到M。
小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分数。当小Z 到达N号顶点时游走结束,总分为所有获得的分数之和。
现在,请你对这M条边进行编号,使得小Z获得的总分的期望值最小。
【输入格式】
第一行是正整数N和M,分别表示该图的顶点数 和边数,接下来M行每行是整数u,v(1≤u,v≤N),表示顶点u与顶点v之间存在一条边。 输入保证30%的数据满足N≤10,100%的数据满足2≤N≤500且是一个无向简单连通图。
【输出格式】
仅包含一个实数,表示最小的期望值,保留3位小数。
【样例输入】
3 3 2 3 1 2 1 3
【样例输出】
3.333
【提示】
边(1,2)编号为1,边(1,3)编号2,边(2,3)编号为3。
这道题目,先求每个点经过的期望次数,我觉得一般是用正推的,然后贪心。
1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdio> 5 #include <cmath> 6 using namespace std; 7 const int N=510,M=N*N; 8 int n,m,e[M][2],d[N]; 9 long double A[N][N];10 double ans,w[M],x[N];11 void Guass_Elimination(){12 for(int i=1;i<n;i++){13 int p=i;14 for(int j=i+1;j<n;j++)15 if(fabs(A[p][i])<fabs(A[j][i]))16 p=j;17 if(p!=i)18 for(int j=1;j<=n;j++)19 swap(A[i][j],A[p][j]);20 long double tmp=A[i][i];21 for(int j=1;j<=n;j++)22 A[i][j]/=tmp;23 for(int j=1;j<n;j++)24 if(i!=j){25 tmp=A[j][i];26 for(int k=1;k<=n;k++)27 A[j][k]-=tmp*A[i][k];28 }29 }30 for(int i=1;i<n;i++)31 x[i]=A[i][n];32 }33 int main(){34 freopen("walk.in","r",stdin);35 freopen("walk.out","w",stdout);36 scanf("%d%d",&n,&m);37 for(int i=1;i<=m;i++){38 scanf("%d%d",&e[i][0],&e[i][1]);39 d[e[i][0]]+=1;d[e[i][1]]+=1;40 }A[1][n]=1;41 for(int i=1;i<n;i++)A[i][i]=1;42 for(int i=1;i<=m;i++){43 if(e[i][0]==n||e[i][1]==n)continue;44 A[e[i][0]][e[i][1]]+=-1.0/d[e[i][1]];45 A[e[i][1]][e[i][0]]+=-1.0/d[e[i][0]];46 }47 Guass_Elimination();48 for(int i=1;i<=m;i++){49 w[i]+=x[e[i][0]]/d[e[i][0]];50 w[i]+=x[e[i][1]]/d[e[i][1]];51 }52 sort(w+1,w+m+1);53 for(int i=1;i<=m;i++)54 ans+=w[i]*(m-i+1);55 printf("%.3lf\n",ans); 56 return 0;57 }
数学(概率):HNOI2013 游走
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。