1690: [Usaco2007 Dec]奶牛的旅行

来源:互联网 发布:麦克海尔数据 编辑:程序博客网 时间:2024/06/05 05:58

题目链接

题目大意:有向图,点有点权,边有边权,奶牛想要从某点出发,走一些路使得经过的点权和除以边权和最大

题解:经典的最优比例环问题,01分数规划
aibi
LLLF(L)0L

我的收获:分数规划get

#include <iostream>#include <cstdio>#include <cstring>using namespace std;#define eps 1e-4#define N 1005#define M 5005int n,m,t;int f[N],head[N]; bool flag,mark[N];double dis[N];struct edge{int to,nex,str;double val;}e[M];void add(int u,int v,int w){e[t].to=v,e[t].nex=head[u],e[t].str=w;head[u]=t++;}void rebuild(double x){     for(int i=1;i<=n;i++)         for(int j=head[i];j!=-1;j=e[j].nex)             e[j].val=e[j].str*x-f[e[j].to];}void spfa(int x){     mark[x]=1;     for(int v,i=head[x];i!=-1;i=e[i].nex)     if(dis[v=e[i].to]>dis[x]+e[i].val){        if(mark[v]){flag=1;return;}        else dis[v]=dis[x]+e[i].val,spfa(v);     }     mark[x]=0;}bool ok(){     for(int i=1;i<=n;i++) dis[i]=mark[i]=0;     flag=0;     for(int i=1;i<=n;i++){spfa(i);if(flag) return 1 ;}     return 0;}void work(){    double ans;    for(double l=0,r=10000;r-l>eps;){        double mid=(l+r)/2.0;        rebuild(mid);        if(ok()) l=mid,ans=mid;        else r=mid;    }    printf("%.2lf",ans);}void init(){    cin>>n>>m;    memset(head,-1,sizeof(head));t=0;    for(int i=1;i<=n;i++) scanf("%d",&f[i]);    int x,y,z;    for(int i=1;i<=m;i++) scanf("%d%d%d",&x,&y,&z),add(x,y,z);}int main(){    init();    work();    return 0;}
阅读全文
0 0
原创粉丝点击