zoukankan      html  css  js  c++  java
  • bzoj1690[Usaco2007 Dec]奶牛的旅行*

    bzoj1690[Usaco2007 Dec]奶牛的旅行

    题意:

    n点m边有向图,点有点权,边有边权,奶牛想要从某点出发,走一些路使得经过的点权和除以(浮点数除法)边权和最大,求这个小数(保留两位)。n≤1000,m=5000。

    题解:

    01分数规划!太神了,然而我看不懂证明,所以直接给出算法。假设需要所求小数最大,那么二分这个数,然后将所有边的边权改为分母(需要最小化的部分)*二分的数-分子(需要最大化的部分),然后判负环。如果有,说明解合法,否则解不合法。最后把下界输出。如果需要所求小数最小,则把边权改为分子(需要最大化的部分)-分母(需要最小化的部分)*二分的数,同时改变范围缩小的方向。

    而判负环用dfs实现的spfa较快,而且每个节点都必须作为起点遍历一遍以防漏判负环。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <queue>
     5 #define inc(i,j,k) for(int i=j;i<=k;i++)
     6 #define maxn 1010
     7 #define INF 0x3fffffff
     8 using namespace std;
     9 
    10 inline int read(){
    11     char ch=getchar(); int f=1,x=0;
    12     while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
    13     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    14     return f*x;
    15 }
    16 struct e{int t; double w; int n;}es[maxn*5]; int g[maxn],ess;
    17 void pe(int f,int t){es[++ess]=(e){t,0,g[f]}; g[f]=ess;}
    18 double v[maxn],w[maxn*5]; int n,m;
    19 void rebuild(double x){inc(i,1,m)es[i].w=w[i]*x-v[es[i].t];}
    20 bool ins[maxn],f; double d[maxn];
    21 void dfs(int x){
    22     ins[x]=1;
    23     for(int i=g[x];i;i=es[i].n){
    24         if(f)return;
    25         if(d[es[i].t]>d[x]+es[i].w){
    26             if(ins[es[i].t]){f=1; return;} d[es[i].t]=d[x]+es[i].w; dfs(es[i].t);
    27         }
    28     }
    29     ins[x]=0;
    30 }
    31 bool spfa(){
    32     memset(ins,0,sizeof(ins)); memset(d,0,sizeof(d)); f=0;
    33     inc(i,1,n){dfs(i); if(f)return 0;} return 1;
    34 }
    35 int main(){
    36     n=read(); m=read(); inc(i,1,n)v[i]=read(); inc(i,1,m){int x=read(),y=read(); w[i]=read(); pe(x,y);}
    37     double l=1,r=10000;
    38     while(r-l>0.001){
    39         double mid=(l+r)/2; rebuild(mid); if(!spfa())l=mid;else r=mid;
    40     }
    41     printf("%.2lf",l); return 0;
    42 }

    20160921

  • 相关阅读:
    phpcms V9实现QQ登陆OAuth2.0
    PHP程序员的技术成长规划(送给迷茫的你)
    php实现冒泡排序
    php实现堆排序
    网络抓包以及进行简单数据分析
    网络编程之套接字(tcp)
    网络编程之套接字(udp)
    C语言之位运算
    linux线程及互斥锁
    嵌入式常用英文缩写及单词整理
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/5901703.html
Copyright © 2011-2022 走看看