很不错的一道网络流的题目

二分答案是显然的

首先不考虑每个饼干只能一个老鼠吃

那很显然的建图就是将时间点按照开始结束的点分成2*n-1段

然后对每一段时间建m个老鼠的点,然后s-它限流,再从它到目前可以运行的饼干

那么考虑加上限制每个饼干只能被一个老鼠吃

我们可以考虑一下进行差分

将s-老鼠的值变成差分后的值(当然还得乘以相应个数) 同理老鼠到饼干也类似的连(就不用乘以相应个数了)

为什么这样做是可以的呢?

因为 我们可以把每一个决策都用这里差分的值来表示出来

那还有一个问题就是有的状态实际上是看似不存在的

比如有v1,v2,v3

那么如果没有v2-v1,v1只有v3-v2这个状态实际是不存在的

但是这个一定是比v3状态吃的要小的,即用比限制时间少的v3是一定能达到这个状态的

所以这个是对的

另外:由于几乎没用过c++实数的原因 被坑的很惨

刚开始以为是eps出问题导致精度不足。。后来发现对于精度要求高这不能用cout

long double在精度上高于double

输出时要转换成double输出

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll maxn=;
#define INF 1e9
#define exp 1e-6
ll n,m,s,t,l,sum;
ll head[maxn],d[maxn],p[maxn],r[maxn];
ll dd[maxn],ss[maxn];
bool vis[maxn];
struct re{
ll a,b;
long double c,flow;
}a[maxn];
void arr(ll x,ll y,long double z)
{
a[++l].a=head[x];
a[l].b=y;
a[l].c=z;
a[l].flow=;
head[x]=l;
}
bool bfs()
{
memset(vis,,sizeof(vis));
queue<ll> q;
q.push(s);
d[s]=; vis[s]=;
while (!q.empty())
{
ll x=q.front();q.pop();
ll u=head[x];
while (u)
{
ll v=a[u].b;
if (!vis[v]&&a[u].c>a[u].flow)
{
vis[v]=;
d[v]=d[x]+;
q.push(v);
}
u=a[u].a;
}
}
return vis[t];
}
long double dfs(ll x,long double y)
{
if (x==t||y==) return y;
long double flow=,f;
ll tmp;
ll u=head[x];
while (u)
{
ll v=a[u].b;
if (d[x]+==d[v]&&(f=dfs(v,min(y,a[u].c-a[u].flow)))>)
{
a[u].flow+=f;
if (u%) tmp=u+; else tmp=u-;
y-=f;
a[tmp].flow-=f;
flow+=f;
if (y==) break;
}
u=a[u].a;
}
return flow;
}
long double maxflow()
{
long double flow=;
while (bfs())
{
flow+=dfs(s,INF);
}
return flow;
}
struct ree{
long double a;
ll b;
}b[maxn];
bool cmp(ree a,ree b)
{
return(a.a<b.a);
}
bool cmp2(ll x,ll y)
{
return(x<y);
}
bool check(long double x)
{
for (ll i=;i<=n;i++)
{
b[i*-].a=r[i]; b[i*].a=dd[i]+x;
b[i*].b=i*; b[i*-].b=i*-;
}
sort(b+,b+*n+,cmp);
l=;memset(head,,sizeof(head));
ll last2=;
s=; t=(*n-)*m+n+;
for (ll i=;i<=n;i++)
{
arr((*n-)*m+i,t,p[i]);
arr(t,(*n-)*m+i,);
}
for (ll i=;i<=*n-;i++)
{
for (ll j=;j<=m;j++)
{
arr(,j+last2,(m-j+)*(ss[j]-ss[j-])*(b[i+].a-b[i].a));
arr(j+last2,,);
}
for (ll k=;k<=n;k++)
if (r[k]<=b[i].a&&dd[k]+x>=b[i+].a)
for (ll j=;j<=m;j++)
{
arr(j+last2,(*n-)*m+k,(b[i+].a-b[i].a)*(ss[j]-ss[j-]));
arr((*n-)*m+k,j+last2,);
}
last2+=m;
}
ll to=maxflow();
if (to==sum) return();
else return ();
}
int main()
{
freopen("cheese.in","r",stdin);
freopen("cheese.out","w",stdout);
ll T;
cin>>T;
for (ll i=;i<=T;i++)
{
cin>>n>>m; sum=;
for (ll i=;i<=n;i++)
{
cin>>p[i]>>r[i]>>dd[i];
sum+=p[i];
}
for (ll i=;i<=m;i++)
cin>>ss[i];
sort(ss+,ss+m+,cmp2);
long double hh=,tt=1e9;
while ((tt-hh)>exp)
{ long double mid=(hh+tt)/;
if (check(mid)) tt=mid; else hh=mid;
}
double tmp=tt;
printf("%.9f\n",tmp);
}
return ;
}

[ZJOI2010]贪吃的老鼠的更多相关文章

  1. Luogu2570 [ZJOI2010]贪吃的老鼠 ---- 网络流

    Luogu2570  [ZJOI2010]贪吃的老鼠 题面描述 https://www.luogu.org/problemnew/show/P2570 然后题意大概就是m只老鼠,然后吃n个奶酪,已知 ...

  2. Luogu P2570 [ZJOI2010]贪吃的老鼠

    Luogu P2570 [ZJOI2010]贪吃的老鼠 题目描述 奶酪店里最近出现了\(m\)只老鼠!它们的目标就是把生产出来的所有奶酪都吃掉.奶酪店中一天会生产\(n\)块奶酪,其中第\(i\)块的 ...

  3. [ZJOI2010]贪吃的老鼠(网络流+建图)

    题目描述 奶酪店里最近出现了m只老鼠!它们的目标就是把生产出来的所有奶酪都吃掉.奶酪店中一天会生产n块奶酪,其中第i块的大小为pi,会在第ri秒被生产出来,并且必须在第di秒之前将它吃掉.第j只老鼠吃 ...

  4. [ZJOI2010]贪吃的老鼠 网络流

    ---题面--- 题解: 这是一道强题emmmm,做法非常巧妙,,,我也是看了好久大佬题解才看明白一点 首先考虑没有限制的情况,即n个老鼠可以在同一时刻吃同一块奶酪 对各个时间段拆点,连奶酪 ---& ...

  5. Luogu2570 ZJOI2010 贪吃的老鼠 二分答案+最大流

    题目链接:https://www.luogu.org/problemnew/show/P2570 题意概述: 好像没什么好概述的.....很简洁? 分析: 首先想到二分时间,转化成判定性问题,在一定时 ...

  6. 【题解】ZJOI2010贪吃的老鼠

    %%%%真的好强...看题解我都看了好久才完全明白.放一下参考的博客,谢谢神犇QAQ 1号博客    2号博客(超级赞的啦) 因为理解的过程太艰辛,所以必须记录一下这道强题:这道题目最难的两个约束就在 ...

  7. luogu P2570 [ZJOI2010]贪吃的老鼠【二分+最大流】

    首先考虑只满足第一个条件,二分答案,把过期时间加上mid之后的2n个时间离散,老鼠拆成每个时间的,第i个时间第j个老鼠为id[i][j],连接(s,i,p[i]),对于离散后时间(g[j-1]~g[j ...

  8. P2570 [ZJOI2010]贪吃的老鼠

    传送门 →_→唯一一篇能看得懂的题解---->这里 很容易想到二分+网络流,然而并没有什么卵用--出题人的思路太神了-- 首先考虑如果一块奶酪在同一时间可以被多只老鼠吃的话,该如何建图.首先不难 ...

  9. 洛谷$P2570\ [ZJOI2010]$贪吃的老鼠 网络流+二分

    正解:网络流+二分 解题报告: 传送门$QwQ$ 和上一题有点儿像,,,?$QwQ$但是比上一题要有趣很多$QwQ$ 首先把大致思路捋下?依然是.二分出每个奶酪的开始和结束时间,然后check下最大流 ...

随机推荐

  1. 微信接口开发之高级篇系列【微信JS-SDK】

    PHP微信公众平台开发高级篇—微信JS-SDK 第一步.绑定域名: 第二步.引入JS文件: 第三部.通过Config接口注入权限验证配置 第四部.通过Read接口处理成功验证 第五部.通过Error接 ...

  2. u-boot移植(九)---代码修改---NAND

    一.NAND原理 NAND 无地址空间,地址和数据的发送都依赖于LDATA[0:7]这一串数据总线. 不看随机页编程,看到从高位到低位的页,总共分为64个页面,每个页的组成是2K + 64  个byt ...

  3. 绕过CDN查看网站真实IP的一些办法

    验证是否存在CDN最简单的办法 通过在线的多地ping,通过每个地区ping的结果得到IP. 看这些IP是否一致,如果都是一样的,极大可能不存在cdn,但不绝对. 如果这些IP大多数都不太一样或者规律 ...

  4. Listbox的操作,数据源变化时要及时更新listbox要先把数据源置空,在给数据源绑定数据

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  5. yo install generator-gulp-react遇到UNMET PEER DEPENDENCY问题

    最近在用yeoman下载下来的框架配置react环境 yo install generator-gulp-react安装框架包 遇到了 UNMET PEER DEPENDENCY问题 找不到依赖的gu ...

  6. django(二)中间件与面向切面编程

    一.中间件概念 django 自带函数可以在几个环节调节收到请求.处理请求.处理异常.以及发送请求. 看这里给的链接好了,这是一个大佬的讲django中间件的博客,非常清楚:https://www.c ...

  7. gflags命令行参数解析

    gflags库是google开源的命令行参数解析工具. 安装 官方没有提供二进制库,但是Debian/Ubuntu平台本身提供了二进制库,可以直接git clone https://github.co ...

  8. Java 集合和映射表

    集合 可以使用集合的三个具体类HashSet.LinkedHashSet.TreeSet来创建集合 HashSet类 负载系数 当元素个数超过了容量与负载系数的乘积,容量就会自动翻倍 HashSet类 ...

  9. nodejs对mongodb数据库的增删改查操作(转载)

    首先要确保mongodb的正确安装,安装参照:http://docs.mongodb.org/manual/tutorial/install-mongodb-on-debian-or-ubuntu-l ...

  10. Python基础-封装与扩展、静态方法和类方法

    一.封装与扩展 封装在于明确区分内外,使得类实现者可以修改封装内的东西而不影响外部调用者的代码:而外部使用者只知道一个接口(函数),只要接口(函数)名.参数不变,使用者的代码永远无需改变.这就提供一个 ...