题目大意:在一个无向连通图上随机游走,初始在1,每一步等概率选择某条出边走到下一个顶点,获得等于这条边的编号的分数;到达 n 结束
对边进行编号,最小化期望总分
题解:详细的题解……
我的收获:各种转化……妙啊
#include<cstdio>
#include<algorithm>
#define N 502
#define M 202222
int n,m,i,x,y,du[N],n1[M],n2[M];
double a[N][N],w[M],ans;
void gauss(){
int now=1,to;double t;
for(int i=1;i<=n;i++){
t=a[now][i];
for(int j=1;j<=n+1;j++)a[now][j]/=t;
for(int j=1;j<=n;j++)
if(j!=now){
t=a[j][i];
for(int k=1;k<=n+1;k++)a[j][k]-=t*a[now][k];
}
now++;
}
}
int main(){
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++){
scanf("%d%d",&n1[i],&n2[i]);
du[n1[i]]++;du[n2[i]]++;
}
for(i=1;i<=m;i++){
a[n1[i]][n2[i]]-=1.0/du[n2[i]];
a[n2[i]][n1[i]]-=1.0/du[n1[i]];
}
for(i=1;i<n;i++)a[i][i]=1,a[i][n]=0;
a[1][n]=1;n--;
gauss();n++;
for(i=1;i<=m;i++)w[i]=a[n1[i]][n]/du[n1[i]]+a[n2[i]][n]/du[n2[i]];
std::sort(w+1,w+m+1);
for(i=1;i<=m;i++)ans+=(m-i+1)*w[i];
printf("%.3lf",ans);
}