[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;
}

原文地址:https://www.cnblogs.com/812-xiao-wen/p/10367014.html

时间: 2024-10-11 00:50:03

[USACO 2001 OPEN]地震 (二分答案+最小生成树)的相关文章

[USACO 2001 OPEN] 地震

好像是 01 分数规划 板子 列出式子 (F - ∑Ci) / (∑Ti) 设当前二分的答案为 ans 若 ans ≤ (F - ∑Ci) / (∑Ti)则说明 ans 可以再增大 那我们二分边界调整的条件就有了 就是当 F - (∑ans*Ti + ∑Ci) ≥ 0 代码: #include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <

【POJ3657】【USACO 2008 Jan Gold】 1.Haybale Guessing 二分答案,并查集check

题意: 输入n.m表示数列长度为n,有m条有序的限制{l,r,x}. 限制:l~r间所有数最小值为x. 问到第几条限制开始出现矛盾,都不出现输出"0". 题解: 首先这题比较厉害,正常解有点难,不妨转化成二分答案. 我们二分"答案",也就是第ans条出现矛盾. 考虑到若一条限制S所在区间被另一个限制Seg包含,且Seg这条限制的x又比S.x大, 那么也就是意为 ① [Seg.l,Seg.r]间最小值为Seg.x ② [S  .l,S  .r]间最小值为S  .x ③

Luogu P1396 营救【最小生成树/二分答案/最短路】 By celur925

题目描述 "咚咚咚--""查水表!"原来是查水表来了,现在哪里找这么热心上门的查表员啊!小明感动的热泪盈眶,开起了门-- 妈妈下班回家,街坊邻居说小明被一群陌生人强行押上了警车!妈妈丰富的经验告诉她小明被带到了t区,而自己在s区. 该市有m条大道连接n个区,一条大道将两个区相连接,每个大道有一个拥挤度.小明的妈妈虽然很着急,但是不愿意拥挤的人潮冲乱了她优雅的步伐.所以请你帮她规划一条从s至t的路线,使得经过道路的拥挤度最大值最小. 输入输出格式 输入格式: 第一行四

【二分答案】【哈希表】【字符串哈希】bzoj2946 [Poi2000]公共串

二分答案,然后搞出hash值扔到哈希表里.期望复杂度O(n*log(n)). #include<cstdio> #include<cstring> #include<vector> using namespace std; typedef unsigned long long ull; const ull seed=29; #define MOD 2007 typedef vector<ull>::iterator VER; vector<ull>

POJ 3258 River Hopscotch 二分答案

River Hopscotch Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6193   Accepted: 2685 Description Every year the cows hold an event featuring a peculiar version of hopscotch that involves carefully jumping from rock to rock in a river. T

BZOJ 1196 HNOI2006 公路修建问题 二分答案+Kruskal

题目大意:给定一个无向图,一条边可以被建为一级公路或二级公路,要求一级公路的数量不小于k条,求最小生成树 最小生成树保证的是最大边最小 直接对边排序,然后二分答案,每次用Kruskal验证 先连一级边看能不能连出k条,再连剩余的边看看能不能得到最小生成树 #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 10100 using nam

[POJ2976][POJ2728]01分数规划问题的二分答案解法

这里就不放原题目了. POJ2976就是01分数规划的模板题,题目形式就是有n个物品,每个物品有对应的价值ai和代价bi,我们要取K个物品,使取的物品的  最小. 二分答案的解法特别妙,我们设 r= ,那么就有   由此不难发现,只要满足这条式子,我们能取的r越大越好. 不难发现此时已经满足二分答案的性质了. 二分r的大小,如果最后式子左边大于0,那么说明r取小了,如果左边小于0,说明r取大了. 那么我的代码如下: #include<iostream> #include<cstdio&g

分治 二分答案 三分未完结

分治,字面上的解释是"分而治之",就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题--直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并.分治法是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)等等. 分治三步法: 1 划分问题:把问题划分成元素个数尽量相等的两半: 2 递归求解:把两半元素分别求解: 3 合并问题:把两个已经求解的元素合并成一个: 二分的基本用途是在单调序列或单调函数中做查找操作,注意:二

[乱写]关于二分答案

看到最小值最大/最大值最小一定要往二分答案上想,想了肯定不会吃亏. 二分答案的优越性在于正难则反的思想,如果从已知条件无法得出最优解,那么就假定一个解看是否与已知条件相悖. 部分看似要二分答案的题可以用最小生成树解决.比如模拟赛23的water,最终高度其实就是从一个格子走出去的路径上最大值的最小解.但对每一个格子二分答案显然无法接受,所以可以建图跑最小生成树直接得到每一个格子的解.类似的还有模拟赛24的star way to heaven,不断将点的坐标加入集合中直到上下边界都在集合里,生成树