码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj1486[HNOI2009]最小圈

时间:2016-09-23 23:17:47      阅读:244      评论:0      收藏:0      [点我收藏+]

标签:

bzoj1486[HNOI2009]最小圈

题意:

定义图中一个环的平均值为环上边权和除以(浮点除法)边数,求一个图中的最小环平均值,保留8位。n≤3000,m≤10000,有负权边。

题解:

这就是比较明显的01分数规划了,见bzoj1690。同时根据题解二分60次就行了。

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define inc(i,j,k) for(int i=j;i<=k;i++)
#define maxn 3010
#define INF 0x3fffffff
using namespace std;

inline int read(){
    char ch=getchar(); int f=1,x=0;
    while(ch<0||ch>9){if(ch==-)f=-1; ch=getchar();}
    while(ch>=0&&ch<=9)x=x*10+ch-0,ch=getchar();
    return f*x;
}
struct e{int t; double w; int n;}es[maxn*4]; int g[maxn],ess;
void pe(int f,int t){es[++ess]=(e){t,0,g[f]}; g[f]=ess;}
double w[maxn*4]; int n,m;
void rebuild(double x){inc(i,1,m)es[i].w=w[i]-x;}
bool ins[maxn],f; double d[maxn];
void dfs(int x){
    ins[x]=1;
    for(int i=g[x];i;i=es[i].n){
        if(f)return;
        if(d[es[i].t]>d[x]+es[i].w){
            if(ins[es[i].t]){f=1; return;} d[es[i].t]=d[x]+es[i].w; dfs(es[i].t);
        }
    }
    ins[x]=0;
}
bool spfa(){
    memset(ins,0,sizeof(ins)); memset(d,0,sizeof(d)); f=0;
    inc(i,1,n){dfs(i); if(f)return 0;} return 1;
}
int main(){
    n=read(); m=read(); inc(i,1,m){int x=read(),y=read(); scanf("%lf",&w[i]); pe(x,y);}
    double l=-10000000,r=10000000; int t=60;
    while(t--){
        double mid=(l+r)/2; rebuild(mid); if(!spfa())r=mid;else l=mid;
    }
    printf("%.8lf",l); return 0;
}

 

20160922

bzoj1486[HNOI2009]最小圈

标签:

原文地址:http://www.cnblogs.com/YuanZiming/p/5901741.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!