【题意】:

有一个烤箱,烤箱在一个时刻最多考M个肉串,N个顾客,每个顾客有属性s,n,e,t s是来的时间,n是想要的肉串数量,e是最晚离开的时间,t是烤的时间(几分熟)。

顾客的烤肉可以分开烤,比如一串烤肉烤的时间是t,那么分成t分就可以在1的时间内烤完。问能否满足所有的顾客。

很像HDU3527

【思路】:

以时间作为流

每个单位时间只能烤M个肉,那么如果一个顾客的属性为s, n, e, t,那么如果满足n*t <= (t-s)*M则这个顾客是可以被满足的。

那么问题可以转换成区间覆盖问题:线段上每个单位容量为M,每个顾客的区间为[s, e],顾客容量为n*t,问能否覆盖完全。

【建图】:

类似HDU3527

设立超级源点sp = 0,sp向每个顾客i连边,权重为n*t,每个单位时间向超级汇点tp连边,权重为M,顾客向时间点连边,权重为 inf,跑最大流即可。

!!但是注意到s,e的范围是1e6那么这样直接连边的话内存需要1e8,肯定会MLE,所以要进行离散化。

【离散化】:

使用C++ STL unique( array.begin(), array.end() )函数,将时间点s,e进行排序去重,最多可以获得2*N个时间点,2*N-1个区间,遍历每个时间区间j, [l ,r]时

遍历每个顾客i的时间[s, e]如果s<=l && e>=r 则i->j连边,权重为inf。

最后跑最大流,判断是否满流即可。

#include <bits/stdc++.h>
using namespace std; const int maxn = + ;
const int maxm = 1e6 + ;
const int inf = 0x3f3f3f3f;
int n, m, sp, tp, sum, maxflow;
int s[maxn], e[maxn], Time[maxn<<], d[maxn*];
int head[maxn*], tot;
struct edge{
int to, w, next;
} ed[maxm<<];
inline void init(){
sum = sp = ;
tot = ;
memset( head ,-, sizeof(head) );
} inline void add( int u, int v, int w ){
ed[++tot].to = v; ed[tot].w = w; ed[tot].next = head[u]; head[u] = tot;
ed[++tot].to = u; ed[tot].w = ; ed[tot].next = head[v]; head[v] = tot;
} inline bool bfs(){
queue<int> q;
memset( d, , sizeof(d) );
d[sp] = ;
q.push(sp);
while( !q.empty() ){
int x = q.front();
q.pop();
for( int i=head[x]; i!=-; i=ed[i].next ){
int y = ed[i].to;
if( ed[i].w && !d[y] ){
d[y] = d[x] + ;
q.push(y);
if( y==tp ) return ;
}
}
}
return ;
} inline int dfs( int x, int flow ){
if( x==tp ) return flow;
int res = flow, k;
for( int i=head[x]; i!=- && res; i=ed[i].next ){
int y = ed[i].to;
if( ed[i].w && d[y]==d[x]+ ){
k = dfs( y, min(ed[i].w, res) );
if( !k ) d[y] = ;
ed[i].w -= k;
ed[i^].w += k;
res -= k;
}
}
return flow - res;
} inline void dinic(){
int flow = maxflow = ;
while( bfs() ){
while( flow=dfs( sp, inf ) ) maxflow += flow;
}
} int main(){
// freopen("in.txt", "r", stdin);
while( ~scanf("%d%d", &n, &m) ){
init();
int cnt = ;
int num, t;
for( int i=; i<=n; i++ ){
scanf("%d%d%d%d", &s[i], &num, &e[i], &t);
add( sp, i, num*t);
sum += num*t;
Time[cnt++] = s[i];
Time[cnt++] = e[i];
}
sort( Time+, Time+cnt+ );
int top = unique(Time+, Time+cnt+)-(Time+);
tp = n+top+;
for( int i=; i<=top; i++ ){
add( n+i, tp, m*(Time[i]-Time[i-]) ); //时间区间编号i需要映射到i+n,避免与顾客的编号重复
for( int j=; j<=n; j++ ){
if( s[j]<=Time[i-] && e[j]>=Time[i] ) add( j, n+i, inf );
}
}
dinic();
if( maxflow==sum ) puts("Yes");
else puts("No");
} return ;
}

HDU2883 kebab(最大流判断满流 + 离散化 + 区间化点)的更多相关文章

  1. hdu 3572 最大流判断满流

    #include<stdio.h> #include<string.h> #include<queue> using namespace std; #define ...

  2. HDU 3572 Task Schedule(最大流判断满流)

    https://vjudge.net/problem/HDU-3572 题意: 有N个作业和M台机器,每个作业都有一个持续时间P,工作的日期为S~E.作业可以断断续续的在不同机器上做,每台机器每次只可 ...

  3. hdu-3572 Task Schedule---最大流判断满流+dinic算法

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3572 题目大意: 给N个任务,M台机器.每个任务有最早才能开始做的时间S,deadline E,和持 ...

  4. hdu3572 任务分配/最大流判断满流

    题意:将n个任务分配为m个机器,给每个任务需要的天数(无需每天连续),和可以在哪些天去做该任务,求是否存在方案. 典型的任务(X)----天(Y)二分最大流,(因为这里任务是与天的关系)处理器控制流量 ...

  5. hdu3572Task Schedule 最大流,判断满流 优化的SAP算法

    PS:多校联赛的题目质量还是挺高的.建图不会啊,看了题解才会的. 参考博客:http://blog.csdn.net/luyuncheng/article/details/7944417 看了上面博客 ...

  6. hdu2883 最大流,判断满流 优化的SAP算法

    这是09年的多校联赛题目,比10年的难度要大.如果没做过hdu3572,建议先去做.有了解题思维再来做这题. 这题与hdu3572类似.但是1 <= si < ei <= 1,000 ...

  7. HDU3605 Escape(最大流判满流 + 状压)

    [题意]: 有N个人,M个星球,给N*M矩阵,(i, j)为1代表i可以到j星球,0代表不能,问是否能把所有人转移走. [思路]: N的范围为1e6,如果让每个人与星球连边一定TLE,再根据矩阵每一行 ...

  8. poj--1637--Sightseeing tour(网络流,最大流判断混合图是否存在欧拉图)

    Sightseeing tour Time Limit: 1000MS   Memory Limit: 10000KB   64bit IO Format: %I64d & %I64u Sub ...

  9. hdu4888 多校B 最大流以及最大流唯一判断+输出方案

    题意,给一个矩阵,告诉你每行和.每列和,并且限制所填数不大于k,问矩阵是否唯一. 经典建图不说了,第一次遇到判断最大流唯一性的,学习了:用dfs来判断残网中是否还存在环,若存在,则表明绕这个环走一圈, ...

随机推荐

  1. 调用 redis 原子命令,保证多线程安全 的incr命令问题

    redis本身就是事件驱动模型,你incr递增好了,然后get获取判断一下是否超过次数 参考:如何用java实现redis incr的高并发计数器

  2. svn在cleanup 时,提示privious operation has not finished,解决方案

    在updated代码时,svn 提示 上一次操作失败,需要cleanup. 执行cleanup时,提示:cleanup失败,因为上一次操作失败,请先执行cleanup.很幽默的提示. svn的“.sv ...

  3. Python 3.X 练习集100题 04

    输入某年某月某日,判断这一天是这一年的第几天? 方法1: import time test_time = input("请输入日期(年-月-日):") time_struct = ...

  4. 搭建 Docker Swarm 集群

      准备三台主机 A:192.168.1.5 B:192.168.1.7 C:192.168.1.10   Docker Swarm集群中的节点主机开放以下三个端口 2377端口, 用于集群管理通信 ...

  5. Git命令之tag差异比较

    比较两个tag的区别有以下几种方式: 例如两个tag分别为v1.0. v2.0 1. git log v2.0 ^v1.0 查看v2.0上有,而v1.0上没有的部分: 2. git log v1.0. ...

  6. Faiss的学习和入门文章

    可以看这里的文章: https://www.leiphone.com/news/201703/84gDbSOgJcxiC3DW.html https://waltyou.github.io/Faiss ...

  7. 使用预编译库PREBUILT LIBRARY官方说明

    使用预编译库 NDK 支持使用预编译库(同时支持静态库和共享库).此功能有以下两个主要用例: 向第三方 NDK 开发者分发您自己的库(而不分发您的源代码). 使用您自己的库的预编译版本来提升编译速度. ...

  8. WPF设置全局控件样式

    原文:WPF设置全局控件样式 方法: 在资源文件APP.XAML中添加如下资源 <Application x:Class="_360UI.App" xmlns="h ...

  9. C# 多维数组 交错数组的区别,即 [ , ] 与 [ ][ ]的区别 (转载)

    多维数组的声明 在声明时,必须指定数组的长度,格式为 type [lenght ,lenght ,lengh, ... ] , ]; 或声明时即赋值,由系统推断长度 int [,] test1 = { ...

  10. C# Winform 文本框默认提示信息

    private string Notes = "提示文本"; private void textBox1_Leave(object sender, EventArgs e) { / ...