题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2883

Almost everyone likes kebabs nowadays (Here a kebab means pieces of meat grilled on a long thin stick). Have you, however, considered about the hardship of a kebab roaster while enjoying the delicious food? Well, here's a chance for you to help the poor roaster make sure whether he can deal with the following orders without dissatisfying the customers.

Now N customers is coming. Customer i will arrive at time si (which means the roaster cannot serve customer i until time si). He/She will order ni kebabs, each one of which requires a total amount of ti unit time to get it well-roasted, and want to get them before time ei(Just at exactly time ei is also OK). The roaster has a big grill which can hold an unlimited amount of kebabs (Unbelievable huh? Trust me, it’s real!). But he has so little charcoal that at most M kebabs can be roasted at the same time. He is skillful enough to take no time changing the kebabs being roasted. Can you help him determine if he can meet all the customers’ demand?

Oh, I forgot to say that the roaster needs not to roast a single kebab in a successive period of time. That means he can divide the whole ti unit time into k (1<=k<=ti) parts such that any two adjacent parts don’t have to be successive in time. He can also divide a single kebab into k (1<=k<=ti) parts and roast them simultaneously. The time needed to roast one part of the kebab well is linear to the amount of meat it contains. So if a kebab needs 10 unit time to roast well, he can divide it into 10 parts and roast them simultaneously just one unit time. Remember, however, a single unit time is indivisible and the kebab can only be divided into such parts that each needs an integral unit time to roast well.

题意描述:有n个人来烤肉店吃烤肉,每个人在si 时刻来ei 时刻离开并且点了ni 份,每份烤肉要烤到ti 个单位时间才算烤熟,烤肉店里可以同时烤m份。问是否有一种计划使得n个人都可以拿到自己的ni 份。
算法分析:这道题本身不是很难,网络流的模型也很常见,但是这道题中(si,ei)的时间跨度很大(1<=si<=ei<=1000000),所以不能把时间区间直接拆分开建立模型,这样顶点个数太多,会超时。这里,介绍一下学到的新技巧,我们可以把时间区间压缩:time[]里保存全部的si 和 ei ,这样time[i]-time[i-1]就表示一段时间区间了,如果这段时间区间在[si,ei]中,那么就把第 i 个人这个顶点和第 i 个时间区间相连接,然后,from->第 i 个人,第 i 个时间区间->to。这样,每一条s-t路径就表示一种烤肉的时间计划了。 
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cstdlib>
  5 #include<cmath>
  6 #include<algorithm>
  7 #include<queue>
  8 #include<vector>
  9 #define inf 0x7fffffff
 10 using namespace std;
 11 const int maxn=600+10;
 12 const int M = 999999;
 13
 14 int n,m,from,to;
 15 int d[maxn];
 16 struct node
 17 {
 18     int v,flow;
 19     int next;
 20 }edge[M*2];
 21 int head[maxn],edgenum;
 22
 23 void add(int u,int v,int flow)
 24 {
 25     edge[edgenum].v=v ;edge[edgenum].flow=flow ;
 26     edge[edgenum].next=head[u];
 27     head[u]=edgenum++;
 28
 29     edge[edgenum].v=u ;edge[edgenum].flow=0;
 30     edge[edgenum].next=head[v];
 31     head[v]=edgenum++;
 32 }
 33
 34 int bfs()
 35 {
 36     memset(d,0,sizeof(d));
 37     d[from]=1;
 38     queue<int> Q;
 39     Q.push(from);
 40     while (!Q.empty())
 41     {
 42         int u=Q.front() ;Q.pop() ;
 43         for (int i=head[u] ;i!=-1 ;i=edge[i].next)
 44         {
 45             int v=edge[i].v;
 46             if (!d[v] && edge[i].flow>0)
 47             {
 48                 d[v]=d[u]+1;
 49                 Q.push(v);
 50                 if (v==to) return 1;
 51             }
 52         }
 53     }
 54     return 0;
 55 }
 56
 57 int dfs(int u,int flow)
 58 {
 59     if (u==to || flow==0) return flow;
 60     int cap=flow;
 61     for (int i=head[u] ;i!=-1 ;i=edge[i].next)
 62     {
 63         int v=edge[i].v;
 64         if (d[v]==d[u]+1 && edge[i].flow>0)
 65         {
 66             int x=dfs(v,min(cap,edge[i].flow));
 67             edge[i].flow -= x;
 68             edge[i^1].flow += x;
 69             cap -= x;
 70             if (cap==0) return flow;
 71         }
 72     }
 73     return flow-cap;
 74 }
 75
 76 int dinic()
 77 {
 78     int sum=0;
 79     while (bfs()) sum += dfs(from,inf);
 80     return sum;
 81 }
 82
 83 int main()
 84 {
 85     while (scanf("%d%d",&n,&m)!=EOF)
 86     {
 87         memset(head,-1,sizeof(head));
 88         edgenum=0;
 89         int s[222],q[222],e[222],t[222];
 90         int time[maxn],cnt=1;
 91         memset(time,0,sizeof(time));
 92         int sum=0;
 93         for (int i=1 ;i<=n ;i++)
 94         {
 95             scanf("%d%d%d%d",&s[i],&q[i],&e[i],&t[i]);
 96             sum += q[i]*t[i];
 97             time[cnt++]=s[i];
 98             time[cnt++]=e[i];
 99         }
100         sort(time+1,time+cnt);
101         int c=0;
102         for (int i=1 ;i<cnt ;i++)
103         {
104             if (time[c] != time[i])
105                 time[++c]=time[i];
106         }
107         from=n+c+1;
108         to=from+1;
109         for (int i=1 ;i<=n ;i++)
110             add(from,i,q[i]*t[i]);
111         for (int i=1 ;i<=c ;i++)
112         {
113             add(n+i,to,m*(time[i]-time[i-1]));
114             for (int j=1 ;j<=n ;j++)
115             {
116                 if (s[j]<=time[i-1] && time[i]<=e[j])
117                     add(j,n+i,inf);
118             }
119         }
120         if (sum==dinic()) printf("Yes\n");
121         else printf("No\n");
122     }
123     return 0;
124 }

转载于:https://www.cnblogs.com/huangxf/p/4328884.html

hdu 2883 kebab 网络流相关推荐

  1. HDU 2883 kebab(离散化+最大流)

    题意:给定n个顾客,第i号顾客在si到达,点了ni个羊肉串,每个羊肉串需要ti个时间烤好.顾客想要在ei得到,一个烤炉只烤m串.问你是否能满足所有顾客的要求?能的话输出"Yes", ...

  2. HDU 6445(竞赛图 + 网络流)

    题意: 给出一个n(<=200)个节点的竞赛图, 计算图中所给的ans. 枚举四元组(a, b, c, d) , 四元组一共有3种情况: 1. 成环 ans ++, 也就是有向环组成的. 2. ...

  3. HDU 4859-海岸线(网络流_最小割)

    海岸线 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submis ...

  4. 网络流 最大流 最小割 费用流

    [腾讯文档]网络流初步 网络流初步 文章目录 网络流初步 一.网络流简介 1. 网络 2. 流 3. 再次理解网络流 二.常见题型(三种) 三.相关问题对应算法介绍 1.最大流 (1) FF算法 - ...

  5. 【转载】图论 500题——主要为hdu/poj/zoj

    转自--http://blog.csdn.net/qwe20060514/article/details/8112550 =============================以下是最小生成树+并 ...

  6. 网络流题集【夏天的风】

    [HDU] 1532Drainage Ditches(基础)    [最大流] 3549 Flow Problem(基础)    [最大流] 3572 Task Schedule    [最大流]任务 ...

  7. HDU 3572 Task Schedule

    传送门 作业调度,这道题还真没想到能用网络流....乍一看跟背包问题差不多. 有N个作业,M个机器,每个作业给你一个耗费时间(时间段)以及最早开始时间和最晚完成时间(这两个是时间点),单位是天.一个作 ...

  8. 【HDOJ图论题集】【转】

    1 =============================以下是最小生成树+并查集====================================== 2 [HDU] 3 1213 How ...

  9. 一系列图论问题[转]

    =============================以下是最小生成树+并查集====================================== [HDU] 1213 How Many ...

最新文章

  1. BAT会看上哪样的中小公司程序员?
  2. fantouch os Android 7,Funtouch OS 3.1 with Android 7.1升级计划
  3. python获取一个月之前日期_Python 获取几天前的时间
  4. vue --- 子组件监听点击事件,接收父组件参数.实现对应跳转
  5. 阿里巴巴微服务开源项目盘点(持续更新)
  6. linux 自定义vi dd,Vim常用命令及配置方案
  7. 没有报表和数据分析,银行数据仓库只能是一盘散沙
  8. 排序算法 快速排序 python 0913
  9. 从月薪5千到财富自由:有远见的人都在做这件事情
  10. linux 代码编辑器软件下载,Visual Studio Code下载
  11. 网站存在后门 收到公安的网络安全限期整改通知书
  12. jq onclick 定义_jq中的onclick绑定事件
  13. C++洛谷题解(6)
  14. 关于Oracle统计中关于操作系统的统计说明,oracle10个/11g的新特点 自动工作量资料档案库(AWR) 文平...
  15. 宽带按流量计费?欢迎讨论!
  16. 自己动手打造mini型QQ
  17. HTML自动回答,自动回复.html
  18. Cell Reports:青年发育过程中脑血流与功能磁共振ALFF耦合
  19. C#如何获取本机网络ip地址
  20. 讲述下我在EBC金融外汇平台交易的真实体验

热门文章

  1. 配置WIN2003远程桌面的客户端连接数
  2. 在Simulink中设计多工位的系列PID控制器Design Family of PID Controllers for Multiple Operating Points
  3. java中引用数据类型和基本数据类型的一些区别(貌似不完整,但会有些启示)
  4. android程序的建立,创建第一个Android程序 HelloWorld
  5. case when then else_啃食Oracle:条件分支表达式CASE
  6. 如何检查python是否安装了pip_如何检测和删除通过pip安装的Python包?
  7. 开奖及送书|《Vue.js权威指南》
  8. Casper Labs成为数据隐私协议联盟的创始成员
  9. 《时代周刊》四份NFT杂志封面拍卖结束,总售价为276 ETH
  10. SAP License:更改物料基本计量单位