zoukankan      html  css  js  c++  java
  • G. 铁路修复计划 最小生成树

    G. 铁路修复计划

    二分答案,改变边的权值,找最小生成树即可。

    类似的思想还可以用在单度限制最小生成树和最优比例生成树上。

    #include<iostream>
    #include<cmath>
    #include<vector>
    #include<set>
    #include<map>
    #include<algorithm>
    #include<stack>
    #include<cstdio>
    #include<cstdlib>
    using namespace std;
    typedef long long int LL;
    double k;
    int n,m;double M;
    struct edge
    {
     int from;int to;
     LL cost;int foreign;	
     bool operator <(const edge &b)const
     {
      return (cost+foreign*(k-1.)*cost)<(b.cost+b.foreign*(k-1.)*b.cost);
     }
    };
    const int maxn=100000+5;
    edge e[maxn];
    int belong[maxn];
    int be(int x)
    {
     if(x==belong[x])return x;
     	else return belong[x]=be(belong[x]);
    }
    bool ex(double mid)
    {
     k=mid;
     sort(e,e+m);
     for(int i=1;i<=n;i++)belong[i]=i;
     double ansnow=0;
     for(int i=0;i<m&&ansnow<=M;i++)
     	{
     	 
     	 int u=e[i].from,v=e[i].to;
     	 u=be(u);v=be(v);
     	 //cout<<"ll"<<u<<v<<endl;
     	 if(u!=v){ansnow+=(e[i].cost+e[i].foreign*(k-1.)*e[i].cost),belong[v]=u;}
     	 //cout<<ansnow<<endl;
    	}
     return ansnow<=M;
    }
    int main()
    {
    // freopen("t.txt","r",stdin);
     LL MM;
     scanf("%d%d%lld",&n,&m,&MM);
     M=(double)MM;
     //cout<<M<<endl;
     for(int i=0;i<m;i++)
     	scanf("%d%d%d%d",&e[i].from,&e[i].to,&e[i].cost,&e[i].foreign);
     double l=1.0,r=1e+15;
     while((r-l)>1e-8)
     	{
     	 //cout<<"double"<<l<<"  "<<r<<endl;
     	 double mid=(r+l)/2.;
     	 if(ex(mid))l=mid;
     	 	else r=mid;
    	}
     printf("%.6lf",(l+r)/2.);
     return 0;
    }
    

      

  • 相关阅读:
    Practice II 字符串
    Euleriar Path 入门
    2-SAT 入门
    Practice I 图论
    游戏中寻找学习JAVA的乐趣之坦克大战系列5-坦克的动态参数
    JQuery教程:实现轮播图效果
    HTML表格应用
    菜鸟Vue学习笔记(三)
    Java成神路上之设计模式系列教程之一
    JVM垃圾回收机制之对象回收算法
  • 原文地址:https://www.cnblogs.com/heisenberg-/p/6847530.html
Copyright © 2011-2022 走看看