题解
一道结论题,有向图中的最小平均权值回路
最后求的就是这个式子:
滚动数组n*m推一下就好了。
代码
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cctype>
using namespace std;
typedef double db;
const db inf=1e12;
const int N=3030,M=1e4+10;
db f[N][2],pt[N],p[N],w[M],ans=1e7;
int n,m,u[M],v[M],l,r=1;
inline int rd()
{
char ch=getchar();int x=0,f=1;
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+(ch^48);ch=getchar();}
return x*f;
}
int main(){
int i,j;
n=rd();m=rd();
for(i=1;i<=m;++i) {u[i]=rd();v[i]=rd();scanf("%lf",&w[i]);}
for(i=0;i<n;++i,l=r,r=l^1){
for(j=1;j<=n;++j) f[j][r]=inf;
for(j=1;j<=m;++j) f[v[j]][r]=min(f[v[j]][r],f[u[j]][l]+w[j]);
}
for(i=1;i<=n;++i) pt[i]=f[i][l],p[i]=f[i][l]/n;
for(i=1;i<=n;++i) f[i][l]=0;
for(i=0;i<n;++i,l=r,r=l^1){
for(j=1;j<=n;++j) f[j][r]=inf;
for(j=1;j<=m;++j) f[v[j]][r]=min(f[v[j]][r],f[u[j]][l]+w[j]);
for(j=1;j<=n;++j) p[j]=max(p[j],(pt[j]-f[j][r])/(n-i-1));
}
for(i=1;i<=n;++i)
if(pt[i]<1e11) ans=min(ans,p[i]);
printf("%.8lf\n",ans);
}