519 字
3 分钟
BZOJ 3143 [Hnoi2013]游走 高斯消元 概率DP
Description
一个无向连通图,顶点从1编号到N,边从1编号到M。 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分数。当小Z 到达N号顶点时游走结束,总分为所有获得的分数之和。 现在,请你对这M条边进行编号,使得小Z获得的总分的期望值最小。
Input
第一行是正整数N和M,分别表示该图的顶点数 和边数,接下来M行每行是整数u,v(1≤u,v≤N),表示顶点u与顶点v之间存在一条边。 输入保证30%的数据满足N≤10,100%的数据满足2≤N≤500且是一个无向简单连通图。
Output
仅包含一个实数,表示最小的期望值,保留3位小数。
Sample Input
3 3
2 3
1 2
1 3
Sample Output
3.333
题解
用贪心的思想
要使期望最小 那么可以先求出每条边的期望经过次数
然后问题就转化成了求每条边的期望经过次数
可能从u走到v,也可能从v走到u,从u走到v的期望次数等于经过点u的次数/u的度数
这样就转化成了每个点的期望经过次数
易得
这样就建立了一个n-1元方程组
高斯消元解就可以了
代码比较丑
#include<cstring>#include<cstdio>#include<algorithm>#include<cmath>using namespace std;struct edge{ int END,next;}v[500005];int first[505],p,du[505];void add(int a,int b){ v[p].END=b; v[p].next=first[a]; first[a]=p++;}template<typename T>int cmp(const T a,const T b){ return a > b;}double a[505][505],x[505],f[500005];int n,m;void gauss(){ int im,num=1; for(int k=1;k<=n;k++,num++){ im=k; for(int i=k+1;i<=n;i++) if(fabs(a[i][k])>fabs(a[im][k])) im=i; if(im!=k){ for(int i=k;i<=n+1;i++) swap(a[num][i],a[im][i]); } if(!a[num][k]){ num--;continue; } for(int i=num+1;i<=n;i++){ if(!a[num][i])continue; double t=a[i][k]/a[num][k]; for(int j=k;j<=n+1;j++){ a[i][j]-=t*a[k][j]; } } } for(int i=n;i>=1;i--){ for(int j=n;j>=i+1;j--){ a[i][n+1]-=a[i][j]*x[j]; } x[i]=a[i][n+1]/a[i][i]; }}int main(){ //freopen("walk.in","r",stdin); //freopen("walk.out","w",stdout); memset(first,-1,sizeof(first)); scanf("%d%d",&n,&m); int s,e; for(int i=1;i<=m;i++){ scanf("%d%d",&s,&e); du[s]++;du[e]++; add(s,e);add(e,s); } n--; a[1][n+1]=-1; for(int i=1;i<=n;i++){ a[i][i]=-1; for(int j=first[i];j!=-1;j=v[j].next){ if(v[j].END!=n+1) a[i][v[j].END]+=(double)1/(du[v[j].END]); } } gauss(); for(int i=0;i<p;i++){ //if(v[i].END!=n+1) f[i>>1]+=x[v[i].END]/du[v[i].END]; } //for(int i=0;i<m;i++){ // printf("%lf\n",f[i+1]); //} //while(1); sort(f,f+m,cmp<double>); double ans=0; for(int i=0;i<m;i++){ ans+=f[i]*(i+1); } printf("%.3lf",ans); //while(1);}
BZOJ 3143 [Hnoi2013]游走 高斯消元 概率DP
https://www.nekomio.com/posts/20/