【BZOJ1690】【Usaco2007 Dec】奶牛的旅行 分数规划 判断负环

来源:互联网 发布:淘宝网店注册流程 编辑:程序博客网 时间:2024/06/05 17:54

题解:

分数规划+判断负环。

代码:

#include <queue>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define N 1010#define M 5050#define eps 1e-8using namespace std;double mid,fun[N];struct Eli{    int v,n;    double f,l;    void re(){l=mid*f-fun[v];}}e[M];int head[N],cnt;inline void add(int u,int v,double l){    e[++cnt].v=v;    e[cnt].f=l;    e[cnt].n=head[u];    head[u]=cnt;}int n,m,num[N];double dist[N];queue<int>q;bool in[N];bool spfa(){    memset(in,0,sizeof in);    memset(num,0,sizeof num);    memset(dist,0x43,sizeof dist);    while(!q.empty())q.pop();    int i,u,v;    q.push(1),dist[1]=0,num[1]=1;    while(!q.empty())    {        u=q.front(),q.pop(),in[u]=0;        for(i=head[u];i;i=e[i].n)        {            v=e[i].v;            if(dist[v]>dist[u]+e[i].l+eps)            {                if(++num[v]>n)return 1;                dist[v]=dist[u]+e[i].l;                if(!in[v])in[v]=1,q.push(v);            }        }    }    return 0;}bool check(){    for(int i=1;i<=cnt;i++)e[i].re();    return spfa();}int main(){    int i,a,b;    double c;    scanf("%d%d",&n,&m);    for(i=1;i<=n;i++)scanf("%lf",&fun[i]);    for(i=1;i<=m;i++)    {        scanf("%d%d%lf",&a,&b,&c);        add(a,b,c);    }    double l=0,r=1e6;    for(i=60;i--;)    {        mid=(l+r)/2.0;        if(check())l=mid;        else r=mid;    }    printf("%.2lf\n",l);    return 0;}
0 0