[HNOI2013]游走

[HNOI2013]游走
晚上回去写
flag++;

#include <cstdio>
#include <cmath>
#include <algorithm>
const int N = 505;const double eps=1e-8; 
int n,m,ecnt,head[N],d[N],S[N*N],T[N*N];
double f[N][N],q[N*N];
struct Edge{int to,nxt;}e[N*N<<1];
void add(int bg,int ed){e[++ecnt].nxt=head[bg];e[ecnt].to=ed;head[bg]=ecnt;}
void gauss(){
    for(int i=1,now;i<n;i++){
        now=i;
        double tp=f[i][i];
        for(int j=i+1;j<n;j++)
            if(fabs(tp-1.0)-fabs(f[j][i]-1.0)>=eps)now=j,tp=f[j][i];
        if(now!=i) std::swap(f[i],f[now]);
        for(int j=n;j>=i;j--) f[i][j]/=f[i][i];
        for(int j=1;j<n;j++) if(i!=j)
        for(int k=n;k>=i;k--)
            f[j][k]-=f[j][i]*f[i][k];
    }
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1,u,v;i<=m;i++){scanf("%d%d",&u,&v);add(u,v);add(v,u);d[v]++,d[u]++;S[i]=u,T[i]=v;}
    for(int i=1;i<n;i++) {
        f[i][i]=1;
        for(int j=head[i];j;j=e[j].nxt)
            if(e[j].to!=n) f[i][e[j].to]=-1.0/d[e[j].to];
    }
    f[1][n]=1;
    gauss();
    for(int i=1;i<=m;i++){
        if(S[i]!=n)q[i]+=f[S[i]][n]*(1.0/d[S[i]]);
        if(T[i]!=n)q[i]+=f[T[i]][n]*(1.0/d[T[i]]);;
    }
    std::sort(q+1,q+1+m);
    double ans=0;
    for(int i=1;i<=m;i++) ans+=q[i]*(m*1.0-i*1.0+1.0);
    printf("%.3lf",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/sdfzhsz/p/9254027.html