bzoj1486: [HNOI2009]最小圈 分数规划

题目链接

https://www.lydsy.com/JudgeOnline/problem.php?id=1486

题解

这题看了一个非常有意思的写法,有一个求有向图中最小平均权值回路的公式,证明见下http://www.cnblogs.com/y-clever/p/7043553.html

\[ans=\min_{v\in V}\max_{0\leq k\leq n-1}\left[\cfrac{F_n(v)-F_k(v)}{n-k}\right] \]

描述很清楚,看完按公式直接写就是了。(bz空间64mb,卡半天卡不过去,最后用float终于卡过去了!!YY太强辣%%

代码

#include<cstdio>
using namespace std;
const double INF=1e12;
const int maxn=3000+1;
const int maxm=1e4+1; 
int n,m;
int u[maxm],v[maxm];
float w[maxm];
float f[maxn][maxn];
double min(double a,double b){return a<b?a:b;}
double max(double a,double b){return a>b?a:b;}
signed main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++) scanf("%d%d%f",&u[i],&v[i],&w[i]);
    for(int i=1;i<=n;i++) f[0][i]=0.0;
    for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) f[i][j]=INF;
    for(int k=1;k<=n;k++) for(int i=1;i<=m;i++)
    	f[k][v[i]]=min(f[k][v[i]],f[k-1][u[i]]+w[i]);
    double ans=1e7,res;
    for(int i=1;i<=n;i++) if(f[n][i]<1e11){
        double res=-INF;
        for(int j=0;j<n;j++)
            res=max(res,(f[n][i]-f[j][i])/(n-j));
        ans=min(ans,res);
    }
    printf("%.8lf\n",ans);
    return 0;
}

posted @ 2018-10-08 14:32  南城ㄱ  阅读(119)  评论(0编辑  收藏  举报