zoukankan      html  css  js  c++  java
  • [USACO07DEC]观光奶牛Sightseeing Cows(分数规划+判定负环)

    传送门

    双倍经验 代码差不多

    题意:n个点,m条有向边,每个点有一个乐趣值val,经过每条边花费时间wi,求从某一个点出发最后又回到出发点,使平均每单位时间内获得的乐趣值最大.

    分析:设环S={V,E}(V是点集,E是边集).理解题意,我们要求的实际上就是(frac{sum_{i=1}^{k}val[v_i]}{sum_{i=1}^{k}w[e_i]})

    (x=frac{sum_{i=1}^{k}val[v_i]}{sum_{i=1}^{k}w[e_i]})

    整理得(sum_{i=1}^kval[v_i]-x*sum_{i=1}^{k}w[e_i]=0)

    继续得(sum_{i=1}^k(val[v_i]-x*w[e_i])=0)

    (f(x)=sum_{i=1}^k(val[v_i]-x*w[e_i]))

    f(x)随x增大而减小,即f(x)是一个递减函数,既然具有单调性,就要想到二分答案.

    我们直接二分要求的答案x,check时把每条边的边权看作(val[v_i]-x*w[e_i])如果此次二分的值合法,即(frac{sum_{i=1}^kval[v_i]}{sum_{i=1}^{k}w[e_i]}>x),根据上面的推导得(sum_{i=1}^k(val[v_i]-x*w[e_i])>0),即图中存在一个正环.

    我们一般都是求负环吧,所以我们稍稍转换一下,把(sum_{i=1}^k(val[v_i]-x*w[e_i])>0)两边同时乘上-1,变成了(sum_{i=1}^k(-val[v_i]+x*w[e_i])<0)

    所以本题就转换为了二分x,把每条边权看作(-val[v_i]+x*w[e_i]),然后判断图中是否存在负环.

    我写的是dfs+spfa判负环(如果不会判负环,请看广告).

    注意本题是实数域上的二分答案.

    int n,m,tot,visit[1005],val[1005];
    int head[1005],nxt[5005],to[5005],w[5005];
    double eps=1e-4,dis[1005];
    void add(int a,int b,int c){
        nxt[++tot]=head[a];
        head[a]=tot;
        to[tot]=b;
        w[tot]=c;
    }
    bool dfs_spfa(int x,double mid){
        visit[x]=1;
        for(int i=head[x];i;i=nxt[i]){
    		int y=to[i];
    		if(dis[y]>dis[x]-val[x]+mid*w[i]){
    	    	dis[y]=dis[x]-val[x]+mid*w[i];
    	    	if(visit[y]||dfs_spfa(y,mid))
            		return 1;
    		}
        }
        visit[x]=0;
        return 0;
    }
    bool check(double mid){
        memset(visit,0,sizeof(visit));
        for(int i=1;i<=n;i++)dis[i]=0;
        for(int i=1;i<=n;i++)
    		if(dfs_spfa(i,mid))return 1;
        return 0;
    }
    int main(){
        n=read();m=read();
        for(int i=1;i<=n;i++)val[i]=read();
        for(int i=1;i<=m;i++){
    		int a=read(),b=read(),c=read();
    		add(a,b,c);
        }
        double l=-1e9,r=1e9,mid;
        while(l+eps<r){
    		mid=(l+r)/2.0;
    		if(check(mid))l=mid;
    		else r=mid;
        }
        printf("%.2lf
    ",l);
        return 0;
    }
    
    
  • 相关阅读:
    Socket.IO 客户端 API IO
    约束,在ios8 没问题,在ios7崩溃的问题,UItextField
    在Viewdidload里面给self.View加动画无效的问题
    改变UITextField PlaceHolder的字体和颜色,不影响正常输入
    iOS第三方键盘高度获取不准确问题
    tableViewCell的分割线短一截的问题
    iOS开发中模拟器归档成功,但是真机归档失败的问题
    C语言——数组、字符串
    C语言——函数
    C语言——流程控制
  • 原文地址:https://www.cnblogs.com/PPXppx/p/10367298.html
Copyright © 2011-2022 走看看