求最小的获得的期望
很容易想到当边的期望经过数量越小,给予的权值越大
设表示边经过次数的期望,
为经过点出去次数的期望,
为度数
,
要
,
通过移项,可以得到个未知数,
个方程的方程组
高斯消元后求出,进而求出
,进而求出总期望
唯一坑点:要开
,这无疑是想不到
这道题不得说是一道对于初学者来说不错的题目
作为一个对期望一窍不通的弱鸡,我对此还能做出
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#define db long double
const db eps=1e-6;
using namespace std;
const int N=1005,M=1e6+5;
int n,m,deg[N],u[M],v[M];
bool e[N][N];
db a[N][N],ans[N],E[M],s;
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&u[i],&v[i]);
e[u[i]][v[i]]=1;
e[v[i]][u[i]]=1;
deg[u[i]]++;
deg[v[i]]++;
}
ans[n]=0;
for(int i=1;i<=n-1;i++)
{
for(int j=1;j<=n-1;j++)
if(e[i][j]) a[i][j]=(db)1/deg[j];
a[i][i]=-1;
}
a[1][n]=-1;
for(int i=1;i<=n-1;i++)
{
if(abs(a[i][i])<=eps)
for(int j=i+1;j<=n-1;j++)
if(abs(a[j][i])>eps)
{
for(int k=i;k<=n;k++)
swap(a[i][k],a[j][k]);
break;
}
for(int j=i+1;j<=n-1;j++)
if(abs(a[j][i])>eps)
{
db b=a[i][i]/a[j][i];
a[j][i]=0;
for(int k=i+1;k<=n;k++)
a[j][k]=a[j][k]*b-a[i][k];
}
}
for(int i=n-1;i>=1;i--)
{
ans[i]=a[i][n];
for(int j=i+1;j<=n-1;j++)
ans[i]-=a[i][j]*ans[j];
ans[i]/=a[i][i];
}
for(int i=1;i<=m;i++)
E[i]=ans[u[i]]/deg[u[i]]+ans[v[i]]/deg[v[i]];
sort(E+1,E+m+1);
s=0;
for(int i=1;i<=m;i++)
s+=E[i]*(m-i+1);
printf("%.3Lf\n",s);
return 0;
}