本人蒟蒻,反正本只会用高斯消元做这道题,求出每个情况的系数,上期望算法乱搞就行了。
注意高斯消元的for循环,起止点很乱,最好手动推一推。
#include<bits/stdc++.h>
using namespace std;
const int N=505,M=250500;
const int eps=1e-9;
int mp[N][N],d[N],a[M],b[M],m,n;
double C[N][N],val[M],num[N],ans;
template<class T>inline void read(T &res){
static char ch;T flag=1;
while((ch=getchar())<'0'||ch>'9')if(ch=='-')flag=-1;res=ch-48;
while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-48;res*=flag;
}
double ABS(double x){return x<0?-x:x;}
void swap(double &x,double &y){double t=x;x=y;y=t;}
void Gauss(){
for(register int i=1;i<=n-1;i++){
int tmp=i;
for(register int j=i+1;j<=n;++j)if(ABS(C[j][i])>ABS(C[tmp][i])+eps)tmp=j;
if(tmp-i)for(register int j=i;j<=n+1;j++)swap(C[i][j],C[tmp][j]);
for(register int j=i+1;j<=n;j++)
for(register int l=n+1;l>=i;l--)
C[j][l]=C[i][l]*C[j][i]/C[i][i]-C[j][l];
}
for(register int i=n;i>=1;i--){
num[i]=C[i][n+1];
for(register int j=i+1;j<=n;j++)num[i]-=num[j]*C[i][j];
(C[i][i])?num[i]/=C[i][i]:num[i]=0;
}
}
int main(){
read(n),read(m);
for(register int i=1;i<=m;i++){
read(a[i]),read(b[i]);
mp[a[i]][b[i]]++,mp[b[i]][a[i]]++,d[a[i]]++,d[b[i]]++;
}
for(register int i=1;i<=n-2;++i)
for(register int j=1;j<=n-1;++j)
C[i][j]=(i-j)?(1.0*mp[i][j])/d[j]:-1;
for(register int i=1;i<=n-2;++i)C[i][n]=(i-1)?0:-1;
C[n-1][n]=1;
for(register int i=1;i<=n-1;i++)C[n-1][i]=1.0*mp[n][i]/d[i];
num[n--]=0;
Gauss();
for(register int i=1;i<=m;i++)
val[i]=num[a[i]]/(1.0*d[a[i]])+num[b[i]]/(1.0*d[b[i]]);
sort(val+1,val+1+m);
for(register int i=1;i<=m;i++)ans+=val[i]*(m-i+1);
printf("%.3lf\n",ans+eps);
return 0;
}