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

二分答案是显然的

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

那很显然的建图就是将时间点按照开始结束的点分成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. 用 Lua 控制 MIDI 合成器来播放自定义格式乐谱

    用 Lua 控制 MIDI 合成器来播放自定义格式乐谱 作者: FreeBlues 最新: https://www.cnblogs.com/freeblues/p/9936844.html 说明: 本 ...

  2. 二、Internet地址结构

    IP路由器实现的转发程序使用IP地址来识别流量去向.IP地址也表示流量来源. 2.1 IP地址的表示 IPV4地址通常采用点分四组或点分十进制表示法,如192.168.1.1. 点分四组表示法由四个用 ...

  3. Linux之安装虚拟机/虚拟操作系统[VisualBox]

    使用VisualBox安装虚拟机步骤: BIOS开启 Visual Technology(或者 visualization) 安装Visual Box 打开Visual Box > 新建虚拟电脑 ...

  4. Python人工智能之路 - 第四篇 : jieba gensim 最好别分家之最简单的相似度实现

    简单的问答已经实现了,那么问题也跟着出现了,我不能确定问题一定是"你叫什么名字",也有可能是"你是谁","你叫啥"之类的,这就引出了人工智能 ...

  5. mysql 原理 ~ sql执行

    一 普通sql执行的具体过程1 连接器  管理连接,权限验证2 分析器  词法分析,语法分析   比如 数据表和数据列是否存在, 别名是否有歧义,是否符合标准sql语法等3 优化器检测   执行计划生 ...

  6. python - logging模块应用

    logging日志模块应用: import logging # logging.basicConfig( # #定义日志级别,共5个级别,默认级别为warning级别,所以debug和info级别不添 ...

  7. Java的三种代理模式:静态代理/JDK动态代理/Cglib动态代理

    1.静态代理:需要定义接口或者父类,目标对象与代理对象均实现同一接口或继承同一父类. 2.JDK动态代理:需要目标对象实现一个接口,通过动态反射的机制,生成代理对象,实现同一个接口 3.Cglib动态 ...

  8. DSO windowed optimization 代码 (1)

    这里不想解释怎么 marginalize,什么是 First-Estimates Jacobian (FEJ).这里只看看代码,看看Hessian矩阵是怎么构造出来的. 1 优化流程 整个优化过程,也 ...

  9. Spring之JDBCTemplate学习

    一.Spring对不同的持久化支持: Spring为各种支持的持久化技术,都提供了简单操作的模板和回调 ORM持久化技术 模板类 JDBC org.springframework.jdbc.core. ...

  10. ICPC World Finals 2019 题解

    [A]Azulejos 题意简述: 有两排瓷砖,每排都有 \(n\) 个,每个瓷砖有高度 \(h_i\) 和价格 \(p_i\) 两种属性. 你需要分别重新排列这两排瓷砖,使得同一排的瓷砖满足价格不降 ...