题意: 有一个烧烤机,每次最多能烤 m 块肉,现在有 n 个人来买烤肉,每个人到达时间为 si,离开时间为 ei,点的烤肉数量为 ci,点的烤肉所需烘烤时间为 di,
每个人要烤的肉可以分成若干份在同时烤,问是否存在一种方案可以满足所有顾客的需求。
将所有的到达时间和结束时间按升序排序,得到 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 <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
using namespace std;
#define PB push_back
#define MP make_pair
#define REP(i,n) for(int i=0;i<(n);++i)
#define FOR(i,l,h) for(int i=(l);i<=(h);++i)
#define DWN(i,h,l) for(int i=(h);i>=(l);--i)
#define CLR(vis) memset(vis,0,sizeof(vis))
#define MST(vis,pos) memset(vis,pos,sizeof(vis))
#define MAX3(a,b,c) max(a,max(b,c))
#define MAX4(a,b,c,d) max(max(a,b),max(c,d))
#define MIN3(a,b,c) min(a,min(b,c))
#define MIN4(a,b,c,d) min(min(a,b),min(c,d))
#define PI acos(-1.0)
#define INF 1000000000
#define LINF 1000000000000000000LL
#define eps 1e-8
typedef long long ll;
int n,m;
const int mm=222222;
const int mn=2222;
int node,s,t,edge;
int ver[mm],flow[mm],next[mm];
int head[mn],work[mn],dis[mn],q[mn];
int ss[222],e[222],pos[222];
int a[222];
void init(int _node,int _s,int _t)
{
node=_node, s=_s, t=_t;
for(int i=0;i<node;++i)
head[i]=-1;
edge=0;
}
void addedge(int u,int v,int c)
{
ver[edge]=v,flow[edge]=c,next[edge]=head[u],head[u]=edge++;
ver[edge]=u,flow[edge]=0,next[edge]=head[v],head[v]=edge++;
}
bool Dinic_bfs()
{
int i,u,v,l,r=0;
for(i=0;i<node;++i) dis[i]=-1;
dis[ q[r++]=s ] = 0;
for(l=0;l<r;l++)
{
for(i=head[ u=q[l] ]; ~i ;i=next[i])
if(flow[i] && dis[ v=ver[i] ]<0)
{
dis[ q[r++]=v ]=dis[u]+1;
if(v==t) return 1;
}
}
return 0;
}
int Dinic_dfs(int u,int exp)
{
if(u==t) return exp;
for(int &i=work[u],v,temp; ~i ;i=next[i])
{
if(flow[i] && dis[ v=ver[i] ]==dis[u]+1 && ( temp=Dinic_dfs(v,min(exp,flow[i])) )>0)
{
flow[i]-=temp;
flow[i^1]+=temp;
return temp;
}
}
return 0;
}
int Dinic_flow()
{
int ans=0,res,i;
while(Dinic_bfs())
{
for(i=0;i<node;++i) work[i]=head[i];
while( res=Dinic_dfs(s,INF) ) ans+=res;
}
return ans;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
int c,v;
int maxflow=0;
int g=0;
CLR(ss),CLR(e),CLR(pos);
FOR(i,1,n)
{
scanf("%d%d%d%d",&ss[i],&c,&e[i],&v);
pos[i]=c*v;
maxflow+=pos[i];
a[g++]=ss[i];
a[g++]=e[i];
}
sort(a,a+g);
c=0;
FOR(i,1,g-1)
if(a[c]!=a[i])
a[++c]=a[i];
init(n+c+2,0,n+c+1);
FOR(i,1,n)
addedge(s,i,pos[i]);
FOR(i,1,c)
{
addedge(i+n,t,(a[i]-a[i-1])*m);
FOR(j,1,n)
{
if(ss[j]<=a[i-1] && e[j]>=a[i])
addedge(j,i+n,INF);
}
}
int ans=Dinic_flow();
if(ans == maxflow)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}