【题解】ZJOI2010贪吃的老鼠
%%%%真的好强...看题解我都看了好久才完全明白。放一下参考的博客,谢谢神犇QAQ
因为理解的过程太艰辛,所以必须记录一下这道强题:这道题目最难的两个约束就在于:保证一个时间一只老鼠只吃一块奶酪,一个时间一块奶酪只被一只老鼠吃。第一个想法还是相对明显的:二分答案,离散化时间节点(一个节点代表此节点到上一节点之间的时间段)。
最妙的一处是老鼠的拆点。在我们之前离散出来的时间段中,每一段都维护m个老鼠的速度差值。我也不知道原作者是怎么想到建图方式的,所以无法解释思路的走向过程,只能说明一下建图的方式&为什么这样是对的。举个例子:我们现在有三只老鼠,速度分别是:5, 4, 3, 那么我们就可以认为是有3只速度为3(3 - 0 = 3)的老鼠,1只速度为1(4 - 3 = 1)的老鼠,还有一只速度为1(5 - 4 = 1)的老鼠。(为什么后面这两只不一样在后面会解释)。暂且将几只记为id,速度记为v。
s-->每一块奶酪,流量为p[i]; 每一块奶酪-->这个时间段内的老鼠拆点,流量为老鼠拆点v*t(时间); 每一个老鼠拆点-->t,流量为id*v*t。现在让我们来看一下这张图是如何完美的满足了此题的1、2两条约束的:1.保证一个时间一只老鼠只吃一块奶酪:老鼠是按时间段拆的点,连向t,前面所说的拆为了3,1,1的情况,三条都流满说明三只老鼠都在吃,分别流量为1表明速度为3的老鼠在吃...这一点应该还是能够理解的,因为一一对应拆点,必然满足约束。2.保证一个时间一块奶酪只被一只老鼠吃:每一块奶酪都向不同的时间段的拆点通了流量,注意这里的流量并没有乘上id,所以都等于1*v*t,也就满足了一只老鼠的约束。
以下是代码:(没有看懂的只要手抄一次代码,想必就能明白啦!)
#include <bits/stdc++.h>
using namespace std;
#define maxn 100000
#define eps 0.0000001
#define INF 99999999.00
#define db double
int n, m, s, t, cnp, head[maxn], lev[maxn], cur[maxn];
db R, L, tot, p[maxn], r[maxn], d[maxn], T[maxn], v[maxn];
struct edge
{
int to, last;
db c;
}E[maxn]; bool cmp(db a, db b)
{
return a > b;
} void add(int u, int v, db c)
{
E[cnp].to = v, E[cnp].last = head[u], E[cnp].c = c; head[u] = cnp ++;
E[cnp].to = u, E[cnp].last = head[v], E[cnp].c = ; head[v] = cnp ++;
} bool bfs()
{
queue <int> q;
memset(lev, , sizeof(lev));
q.push(s); lev[s] = ;
while(!q.empty())
{
int u = q.front();
q.pop();
for(int i = head[u]; i != -; i = E[i].last)
{
int v = E[i].to;
if(!lev[v] && E[i].c > eps)
{
lev[v] = lev[u] + ;
if(lev[t]) return true;
q.push(v);
}
}
}
return false;
} db dfs(int u, db nf)
{
if(u == t || nf < eps) return nf;
bool done = false;
db ff = 0.0;
for(int i = cur[u]; i != -; i = E[i].last)
{
int v = E[i].to;
if(!nf) break;
if(E[i].c > eps && lev[v] == lev[u] + )
{
done = true;
db af = dfs(v, min(E[i].c, nf));
cur[u] = i;
nf -= af, ff += af;
E[i].c -= af, E[i ^ ].c += af;
}
}
if(!done) lev[u] = -;
return ff;
} db dinic()
{
db flow = 0.0;
while(bfs())
{
memcpy(cur, head, sizeof(head));
flow += dfs(s, INF);
}
return flow;
} void init()
{
cnp = ;
memset(head, -, sizeof(head));
} void solve()
{
db sum = tot; s = , t = * m * n + n + ;
int cnt = ;
while(R - L > eps)
{
db mid = (R + L) / 2.0;
init();
for(int i = ; i <= n; i ++)
{
add(, i, p[i]);
T[ * i - ] = r[i], T[ * i] = d[i] + mid;
}
sort(T + , T + * n + ), cnt = n;
for(int i = ; i <= m; i ++)
{
for(int j = ; j <= * n; j ++)
{
if(T[j] - T[j - ] < eps) continue;
++ cnt; add(cnt, t, i * v[i] * (T[j] - T[j - ]));
for(int k = ; k <= n; k ++)
{
if(r[k] - T[j - ] < eps && (d[k] + mid - T[j] > -eps))
add(k, cnt, v[i] * (T[j] - T[j - ]));
}
}
}
db maxflow = dinic();
if(sum - maxflow < eps) R = mid;
else L = mid;
}
printf("%lf\n", L);
} int main()
{
int T;
scanf("%d", &T);
while(T --)
{
tot = 0.0;
scanf("%d%d", &n, &m);
for(int i = ; i <= n; i ++)
{
scanf("%lf%lf%lf", &p[i], &r[i], &d[i]);
tot += p[i];
}
for(int i = ; i <= m; i ++) scanf("%lf", &v[i]);
sort(v + , v + + m, cmp);
R = (db) tot / v[] + 1.0, L = 0.0;
for(int i = ; i < m; i ++) v[i] -= v[i + ];
solve();
}
return ;
}
【题解】ZJOI2010贪吃的老鼠的更多相关文章
- Luogu2570 [ZJOI2010]贪吃的老鼠 ---- 网络流
Luogu2570 [ZJOI2010]贪吃的老鼠 题面描述 https://www.luogu.org/problemnew/show/P2570 然后题意大概就是m只老鼠,然后吃n个奶酪,已知 ...
- Luogu P2570 [ZJOI2010]贪吃的老鼠
Luogu P2570 [ZJOI2010]贪吃的老鼠 题目描述 奶酪店里最近出现了\(m\)只老鼠!它们的目标就是把生产出来的所有奶酪都吃掉.奶酪店中一天会生产\(n\)块奶酪,其中第\(i\)块的 ...
- [ZJOI2010]贪吃的老鼠(网络流+建图)
题目描述 奶酪店里最近出现了m只老鼠!它们的目标就是把生产出来的所有奶酪都吃掉.奶酪店中一天会生产n块奶酪,其中第i块的大小为pi,会在第ri秒被生产出来,并且必须在第di秒之前将它吃掉.第j只老鼠吃 ...
- [ZJOI2010]贪吃的老鼠 网络流
---题面--- 题解: 这是一道强题emmmm,做法非常巧妙,,,我也是看了好久大佬题解才看明白一点 首先考虑没有限制的情况,即n个老鼠可以在同一时刻吃同一块奶酪 对各个时间段拆点,连奶酪 ---& ...
- P2570 [ZJOI2010]贪吃的老鼠
传送门 →_→唯一一篇能看得懂的题解---->这里 很容易想到二分+网络流,然而并没有什么卵用--出题人的思路太神了-- 首先考虑如果一块奶酪在同一时间可以被多只老鼠吃的话,该如何建图.首先不难 ...
- [ZJOI2010]贪吃的老鼠
很不错的一道网络流的题目 二分答案是显然的 首先不考虑每个饼干只能一个老鼠吃 那很显然的建图就是将时间点按照开始结束的点分成2*n-1段 然后对每一段时间建m个老鼠的点,然后s-它限流,再从它到目前可 ...
- Luogu2570 ZJOI2010 贪吃的老鼠 二分答案+最大流
题目链接:https://www.luogu.org/problemnew/show/P2570 题意概述: 好像没什么好概述的.....很简洁? 分析: 首先想到二分时间,转化成判定性问题,在一定时 ...
- luogu P2570 [ZJOI2010]贪吃的老鼠【二分+最大流】
首先考虑只满足第一个条件,二分答案,把过期时间加上mid之后的2n个时间离散,老鼠拆成每个时间的,第i个时间第j个老鼠为id[i][j],连接(s,i,p[i]),对于离散后时间(g[j-1]~g[j ...
- 洛谷$P2570\ [ZJOI2010]$贪吃的老鼠 网络流+二分
正解:网络流+二分 解题报告: 传送门$QwQ$ 和上一题有点儿像,,,?$QwQ$但是比上一题要有趣很多$QwQ$ 首先把大致思路捋下?依然是.二分出每个奶酪的开始和结束时间,然后check下最大流 ...
随机推荐
- C调用约定__cdecl、__stdcall、__fastcall、__pascal分析
参考原文地址:https://www.cnblogs.com/yenyuloong/p/9626658.html C/C++ 中不同的函数调用规则会生成不同的机器代码,产生不同的微观效果,接下来让我们 ...
- Apache Maven(七):settings.xml
settings.xml 文件中包含settings标签,这个标签可以配置如何去执行Maven.其中包括本地存储库位置,备用远程存储库服务器和身份验证信息等值. 有如下两个位置可能存放这setting ...
- 百度知道芝麻将,申请资格&权限介绍&奖惩制度(简剖)
芝麻将,即百度知道管理员.不及掌握,了解下也是好的. 知道圈子,把注册用户,成为芝麻.一般用户,即小芝麻.芝麻将,就是咱们说的知道管理员. 申请. 芝麻将,申请条件不是很难,难的是后续维护,申请前考虑 ...
- Go搭建一个Web服务器
package main import ( "fmt" "net/http" "strings" "log" ) fun ...
- Infinite Maze CodeForces - 196B
We've got a rectangular n × m-cell maze. Each cell is either passable, or is a wall (impassable). A ...
- R语言学习笔记(十五):获取文件和目录信息
file.info() 参数是表示文件名称的字符串向量,函数会给出每个文件的大小.创建时间.是否为目录等信息. > file.info("z.txt") size isdir ...
- PHP.43-TP框架商城应用实例-后台18-商品属性3-库存量管理
库存量管理 思想:为商品的每个多选属性设置库存量!!要把多选属性排列组合分别指定库存量!! 效果如下:[由商品已经添加的属性决定] 1.建表goods_number{goods_id,goods_nu ...
- 2016年JD工作遇到的问题:1-5,搭建环境和熟悉项目过程中的坑
1.更新不需要权限的项目A,却提示没有权限. 先从Git上更新项目A的代码,提示没有权限. 然后从Git上更新其它项目B的代码,正常. 再更新项目A的代码,正常了. 奇葩问题! 2.Eclipse中, ...
- vuex的使用及持久化state的方式详解
vuex的使用及持久化state的方式详解 转载 更新时间:2018年01月23日 09:09:37 作者:baby格鲁特 我要评论 这篇文章主要介绍了vuex的使用及持久化state的方 ...
- 去掉google play专为手机设计标识
google play上的应用默认都会有个“专为手机设计”的标识 有时应用明明已经针对平板作了优化,但为什么这个标识还在呢,如何去掉这个标识呢,其实只需要两个步骤就好了: 1. 标记为支持高分辨率 & ...