[USACO 2001 OPEN]地震 (二分答案+最小生成树)

题面:[USACO 2001 OPEN]地震

\(solution:\)

\(code:\)

#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>

#define ll long long
#define db double
#define rg register int

using namespace std;

const db cha=1e-9;

struct su{
    int x,y,v,t;db k;
}a[10005];

int n,m,f;
int s[405];

inline int qr(){
    char ch;
    while((ch=getchar())<'0'||ch>'9');
    int res=ch^48;
    while((ch=getchar())>='0'&&ch<='9')
        res=res*10+(ch^48);
    return res;
}

inline bool cmp(su x,su y){return x.k<y.k;}

inline int get(int x){
    if(s[x]==x)return x;
    return s[x]=get(s[x]);
}

inline bool check(db x){
    db res=0;
    for(rg i=1;i<=n;++i)s[i]=i;
    for(rg i=1;i<=m;++i)
        a[i].k=x*a[i].t+(db)a[i].v;
    sort(a+1,a+m+1,cmp);
    for(rg i=1;i<=m;++i)
        if(get(a[i].x)!=get(a[i].y))
            res+=a[i].k,s[get(a[i].x)]=get(a[i].y);
    return f>res?0:1;
}

int main(){
    freopen("quake.in","r",stdin);
    freopen("quake.out","w",stdout);
    n=qr(),m=qr(),f=qr();
    for(rg i=1;i<=m;++i)
        a[i]=su{qr(),qr(),qr(),qr()};
    if(check(0))puts("0.0000"),exit(0);
    db l=0,r=1e14,mid;
    while(r-l>cha){
        mid=(l+r)/2;
        if(check(mid))r=mid-cha;
        else l=mid+cha;
    }printf("%.4lf",l);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/812-xiao-wen/p/10367014.html