[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;
}