[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;
}
posted @ 2018-07-02 15:28  SWHsz  阅读(95)  评论(0编辑  收藏  举报