bzoj 3143: [Hnoi2013]游走

来源:互联网 发布:td-scdma是什么网络 编辑:程序博客网 时间:2024/06/11 20:20

先高斯消元求出每个点期望到达次数,再到边;
再利用排序不等式贪心求解;点1一开始就期望1;
要注意点n的特殊性,它原本期望为1,但每个点不能由它转移过去,
它的期望也与其它点无关,就让它为0以方便计算;

#include<bits/stdc++.h>#define rep(i,k,n) for(int i=k;i<=n;i++)using namespace std;const int maxn=505,maxm=maxn*maxn;typedef double db;int g[maxn][maxn],d[maxn],n,m,s[maxm],t[maxm];db a[maxn][maxn],p[maxn],ans[maxm],Ans=0.0;void gauss(){    rep(i,1,n-1){db ok=0.0;int id=i;        rep(j,i,n-1)if(fabs(a[j][i])>ok){ok=fabs(a[j][i]);id=j;}        if(ok==0.0)continue;        if(id!=i)rep(j,1,n)swap(a[id][j],a[i][j]);        for(int j=n;j>=i;j--)        for(int k=1;k<n;k++)if(k!=i){            a[k][j]-=a[i][j]*a[k][i]/a[i][i];        }    }    rep(i,1,n-1)p[i]=a[i][n]/a[i][i];   }int main(){//freopen("in.in","r",stdin);int u,v;    scanf("%d%d",&n,&m);    rep(i,1,m){scanf("%d%d",&s[i],&t[i]);u=s[i];v=t[i];    g[u][v]++;g[v][u]++;d[u]++;d[v]++;}    rep(i,1,n-1)    rep(j,1,n-1){        if(i==j)a[i][j]=1.0;        else a[i][j]=-1.0*g[i][j]/d[j];    }    a[1][n]=1.0;    gauss();    rep(i,1,m){ans[i]=(p[s[i]]*1.0/d[s[i]])+(p[t[i]]*1.0/d[t[i]]);}    sort(ans+1,ans+1+m);    rep(i,1,m)Ans+=(m-i+1)*1.0*ans[i];    printf("%.3lf",Ans);    return 0;}
0 0
原创粉丝点击