显然只需要求出所有边被经过的期望次数,然后贪心把边权小的边定城大的编号。
所以如何求出所有边被经过的期望次数?
显然这只跟边连接的两个点有关。
于是我们只需要求出两个点被经过的期望次数。
对于一个点
uuu,它被经过的期望次数
f[u]=∑vf[v]/du[v]f[u]=\sum _v f[v]/du[v]f[u]=∑vf[v]/du[v] 这是一个环上的递推式,我们可以用高斯消元解方程组。
代码:
#include #define N 505#define M 250005using namespace std;int n,m,du[N];double matrix[N][N],f[N],ans=0.0;bool tran[N][N];struct edge{ int u,v;double w;}e[M];inline bool cmp(edge a,edge b){ return a.w fabs(matrix[tmp][i]))tmp=j; if(tmp^i)swap(matrix[i],matrix[tmp]); for(int j=i+1;j<=n;++j){ double ttmp=matrix[j][i]/matrix[i][i]; for(int k=i;k<=n+1;++k)matrix[j][k]-=matrix[i][k]*ttmp; } } for(int i=n;i;--i){ for(int j=i+1;j<=n;++j)matrix[i][n+1]-=matrix[i][j]*f[j]; f[i]=matrix[i][n+1]/matrix[i][i]; }}inline int read(){ int ans=0; char ch=getchar(); while(!isdigit(ch))ch=getchar(); while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar(); return ans;}int main(){ n=read(),m=read(); for(int i=1;i<=m;++i){ ++du[e[i].u=read()],++du[e[i].v=read()]; tran[e[i].u][e[i].v]=tran[e[i].v][e[i].u]=true; } matrix[1][n]=1; for(int i=1;i<=n;++i)matrix[i][i]=1; for(int i=1;i