[HNOI2013] 游走
一条边如果期望走的次数越少,那么我们就要给他分配更大的标号,所以我们需要求出每一条边的被走过的次的期望。
而一条边被走过次数的期望就是 , 表示一个点被走过的期望, 表示一个点的度数。
然后就变成了一道经典的高斯消元,列方程求出 。需要注意的是 ,。
#include <bits/stdc++.h>
using namespace std;
const int maxm=125002;
const int maxn=1002;
const double eps=1e-10;
typedef double db;
int n,m;
int X[maxm],Y[maxm];int d[maxn];
db a[maxn][maxn];db ans[maxm];
void solve()
{
int r=0;db t;
for(int i=1;i<=n;i++)
{
r=i;
for(int j=i+1;j<=n;j++)
{
if(fabs(a[j][i])-fabs(a[r][i])>eps)
r=j;
}
if(fabs(a[r][i])<eps) return;
if(r!=i) swap(a[r],a[i]);
for(int k=i+1;k<=n;k++)
{
db ls=a[k][i]/a[i][i];
for(int j=i;j<=n+1;j++)
a[k][j]-=ls*a[i][j];
}
}
for(int i=n;i>=1;i--)
{
for(int j=i+1;j<=n;j++)
a[i][n+1]-=a[j][n+1]*a[i][j];
a[i][n+1]/=a[i][i];
}
}
int main()
{
//freopen("p.in","r",stdin);
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&X[i],&Y[i]);
d[X[i]]++;d[Y[i]]++;
if(X[i]!=n) a[X[i]][Y[i]]=-1.0/d[Y[i]];
if(Y[i]!=n) a[Y[i]][X[i]]=-1.0/d[X[i]];
}
for(int i=1;i<=m;i++)
{
if(X[i]!=n) a[X[i]][Y[i]]=-1.0/d[Y[i]];
if(Y[i]!=n) a[Y[i]][X[i]]=-1.0/d[X[i]];
}
a[1][n+1]=1.0;
for(int i=1;i<n;i++)
{
for(int j=1;j<=n;j++)
{
if(i==j) a[i][j]=1;
//else a[i][j]=-1.0/d[j];
}
}
a[n][n+1]=0;a[n][n]=1;
solve();
//for(int i=1;i<=n;i++)
// fprintf(stderr,"%.5f\n",a[i][n+1]);
for(int i=1;i<=m;i++)
{
ans[i]=a[X[i]][n+1]/d[X[i]]+a[Y[i]][n+1]/d[Y[i]];
}
sort(ans+1,ans+1+m);
db ret=0;
for(int i=1;i<=m;i++)
{
ret+=ans[i]*(m-i+1);
}
printf("%.3lf",ret);
}
本文作者:cc0000
本文链接:https://www.cnblogs.com/cc0000/p/16808169.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步