zoukankan      html  css  js  c++  java
  • [USACO 2001 OPEN]地震(分数规划+最小生成树)

    传送门

    题意:N个牧场,可供修建的道路有M条.奶牛负责修建道路,将所有牧场连通,获得报酬F.每条道路都有自己的施工时间ti和建造成本ci.连接两个相同的牧场的道路可能有多条.保证所有的牧场必定是可连通的,不过也有可能一些道路的建造成本之和会超过F.求选择修建哪些道路,使单位时间的利润(即总利润和总施工时间的比值)的最大.

    分析:理解清楚题意,可以得出我们要求的实际上就是((F-sum{c_i})/sum{t_i})

    (x=(F-sum{c_i})/sum{t_i})

    整理一下得,(F-(sum{c_i}+sum{t_i}*x)=0)

    (f(x)=F-(sum{c_i}+sum{t_i}*x))

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

    我们直接二分要求的答案x,每一次check时把每条边的边权wi更新为(ci+ti*x),然后跑一遍最小生成树,最后判断权值总和与F的大小关系.

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

    const double eps=1e-6;
    //题目要求保留4位小数,精度可以设为1e-(4+2)
    int n,m,f,fa[405];
    struct edge{
        int x,y,c,t;
        double w;//注意边权是实数
    }e[10005];
    bool cmp(edge x,edge y){return x.w<y.w;}
    int find(int x){
        if(fa[x]==x)return x;
        return fa[x]=find(fa[x]);
    }
    bool check(double mid){
        for(int i=1;i<=m;i++)
    		e[i].w=e[i].c*1.0+e[i].t*mid;
    //每一次check时,根据mid值更新边权
    //kruskal跑最小生成树:
        sort(e+1,e+m+1,cmp);
        for(int i=1;i<=n;i++)fa[i]=i;
        int k=0;double now=0;
        for(int i=1;i<=m;i++){
    		int x=find(e[i].x),y=find(e[i].y);
    		if(x!=y){
    	    	k++;
    	    	fa[y]=x;
    	    	now+=e[i].w;
    	    	if(now>f)return 0;
    	    	if(k==n-1)break;
    		}
        }
        return 1;
    }
    int main(){
        n=read();m=read();f=read();
        for(int i=1;i<=m;i++){
    		e[i].x=read();
    		e[i].y=read();
    		e[i].c=read();
    		e[i].t=read();
        }
        double l=-1e9,r=1e9,mid;
    //注意一下二分边界,因为可能出现利润为负数的情况
        while(l+eps<r){//实数域上的二分答案模板
            mid=(l+r)/2;
            if(check(mid))l=mid;
            else r=mid;
        }
        if(r<0)puts("0.0000");//如果利润为负数
        else printf("%.4lf
    ",r);
        return 0;
    }
    
    
  • 相关阅读:
    【Python图像特征的音乐序列生成】解析ABC格式的文件(修改版)
    【Python图像特征的音乐序列生成】关于数据库到底在哪里下载
    假期周进度报告2
    假期周进度报告1
    河北省科技创新平台系统头脑风暴会
    问题账户需求分析
    2018年春季个人阅读计划
    软件需求与分析读后感
    《需求工程——软件建模与分析》读后感3
    《需求工程——软件建模与分析》读后感2
  • 原文地址:https://www.cnblogs.com/PPXppx/p/10366851.html
Copyright © 2011-2022 走看看