【BZOJ】1486最小圈

题解

一道结论题,有向图中的最小平均权值回路
最后求的就是这个式子:
λ = min v V , F n ( v ) max 0 k n 1 [ F n ( v ) F k ( v ) n k ]
滚动数组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);
}

猜你喜欢

转载自blog.csdn.net/corsica6/article/details/80556174