【BZOJ】1486最小圈

题解

一道结论题,有向图中的最小平均权值回路
最后求的就是这个式子:
λ=minvV,Fn(v)max0kn1[Fn(v)Fk(v)nk] λ ∗ = min v ∈ V , F n ( v ) ≠ ∞ max 0 ≤ k ≤ n − 1 [ F n ( v ) − F k ( v ) n − k ]
滚动数组n*m推一下就好了。


代码

#include
#include
#include
#include
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;i1){
        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;i1){
        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);
}

你可能感兴趣的:(妙,结论及推导)