kebab (hdu 2883 网络流判满流 关键是缩点)

kebabTime Limit: 2000/1000 MS (Java/Others)Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1071Accepted Submission(s): 447

Problem Description

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.

Input

There are multiple test cases. The first line of each case contains two positive integers N and M. N is the number of customers and M is the maximum kebabs the grill can roast at the same time. Then follow N lines each describing one customer, containing four integers: si (arrival time), ni (demand for kebabs), ei (deadline) and ti (time needed for roasting one kebab well).There is a blank line after each input block.Restriction:1 <= N <= 200, 1 <= M <= 1,0001 <= ni, ti <= 501 <= si < ei <= 1,000,000

Output

If the roaster can satisfy all the customers, output “Yes” (without quotes). Otherwise, output “No”.

Sample Input

2 101 10 6 32 10 4 22 101 10 5 32 10 4 2

Sample Output

YesNo

Source

2009 Multi-University Training Contest 9 – Host by HIT

Recommend

gaojie|We have carefully selected several similar problems for you:28822884306128882886

题意:有一个烧烤机,每次最多能烤 m 块肉,现在有 n 个人来买烤肉,每个人到达时间为 si,,离开时间为 ei,点的烤肉数量为 ci,每个烤肉所需烘烤时间为 di,注意一个烤肉可以切成几份来烤。

思路:这一题和hdu 3572 Task Schedule有一点点像,但这一题时间的范围跨度太大,不能再每个时刻看成一个点了,要进行缩点,这一点很巧妙,我没想到。将所有的到达时间和结束时间按升序排序,得到 x <= 2n-1 个时间区间。建立网络流模型:s为源,t为汇,每个顾客i作为一个结点并连边(s, i, ni*ti),每个区间j作为一个结点并连边(j, t, (ej-sj)*M),其中sj, ej分别表示区间j的起始时间和终止时间。对任意顾客i和区间j,若 [sj, ej] 完全包含在 [si, ei] 之中,则连边(i, j, INF)。若最大流等于 ∑ni*ti 则是 Yes,否则是 No。

代码:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <string>#include <map>#include <stack>#include <vector>#include <set>#include <queue>#pragma comment (linker,"/STACK:102400000,102400000")#define maxn 1005#define MAXN 2005#define mod 1000000009#define INF 0x3f3f3f3f#define pi acos(-1.0)#define eps 1e-6#define lson rt<<1,l,mid#define rson rt<<1|1,mid+1,r#define FRE(i,a,b) for(i = a; i <= b; i++)#define FREE(i,a,b) for(i = a; i >= b; i–)#define FRL(i,a,b) for(i = a; i < b; i++)#define FRLL(i,a,b) for(i = a; i > b; i–)#define mem(t, v) memset ((t) , v, sizeof(t))#define sf(n)scanf("%d", &n)#define sff(a,b) scanf("%d %d", &a, &b)#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)#define pfprintf#define DBGpf("Hi\n")typedef long long ll;using namespace std;struct Edge{int u,v,cap,next;}edge[MAXN];int n,m,num,sum,cnt;int level[maxn],head[maxn],cur[maxn];int S[maxn],E[maxn],N[maxn],T[maxn],a[maxn];void init(){num=0;cnt=0;sum=0;mem(head,-1);}void addedge(int u,int v,int w){edge[num].u=u; edge[num].v=v; edge[num].cap=w; edge[num].next=head[u]; head[u]=num++;edge[num].u=v; edge[num].v=u; edge[num].cap=0; edge[num].next=head[v]; head[v]=num++;}bool bfs(int s,int t){mem(level,-1);level[s]=0;queue<int>Q;Q.push(s);while (!Q.empty()){int u=Q.front(); Q.pop();for (int i=head[u];i+1;i=edge[i].next){int v=edge[i].v;if (level[v]==-1&&edge[i].cap>0){level[v]=level[u]+1;Q.push(v);}}}return level[t]!=-1;}int dfs(int u,int t,int f){if (u==t) return f;for (int &i=cur[u];i+1;i=edge[i].next){int v=edge[i].v;if (level[v]==level[u]+1&&edge[i].cap>0){int d=dfs(v,t,min(f,edge[i].cap));if (d>0){edge[i].cap-=d;edge[i^1].cap+=d;return d;}}}return 0;}int dinic(int s,int t,int nodenum){int flow=0,f;while (bfs(s,t)){for (int i=0;i<=nodenum;i++) cur[i]=head[i];while ((f=dfs(s,t,INF))>0)flow+=f;}return flow;}int main(){int i,j;while (~scanf("%d%d",&n,&m)){init();for (i=1;i<=n;i++){scanf("%d%d%d%d",&S[i],&N[i],&E[i],&T[i]);a[cnt++]=S[i];a[cnt++]=E[i];sum+=N[i]*T[i];addedge(0,i,N[i]*T[i]);}sort(a,a+cnt);cnt=unique(a,a+cnt)-a;for (i=0;i<cnt-1;i++){addedge(n+i+1,n+cnt,(a[i+1]-a[i])*m);for (j=1;j<=n;j++)if (a[i]>=S[j]&&a[i+1]<=E[j])addedge(j,n+i+1,INF);}int ans=dinic(0,n+cnt,n+cnt+1);//printf("%d\n",ans);if (ans==sum) printf("Yes\n");else printf("No\n");}return 0;}

为何是一个人?也有善意的提醒:

kebab (hdu 2883 网络流判满流 关键是缩点)

相关文章:

你感兴趣的文章:

标签云: