题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=2883
题意
一个烧烤摊,最多同时考M个串,现在给n个顾客信息,分别是到达烧烤店的时间,和他要走的时间,以及需要考的串的个数,和每个串烤熟需要的时间。问给定n个顾客,是否能够满足所有顾客的需求。
思路
从超级源点连边到每个顾客,容量为ni*ti,对于输入的时间区间,将所有点排序去重,然后每个区间连边到超级汇点容量为(l-r)*M。对于原来输入的顾客的区间,如果他完全包含某个区间,那么这个顾客到这个区间连一条边,容量为INF。具体看代码
#include<cstdio>
#include<queue>
#include<iostream>
#include<vector>
#include<map>
#include<cstring>
#include<string>
#include<set>
#include<stack>
#include<algorithm>
#define cle(a) memset(a,0,sizeof(a))
#define inf(a) memset(a,0x3f,sizeof(a))
#define ll long long
#define Rep(i,a,n) for(int i=a;i<=n;i++)
using namespace std;
const int INF = ( 2e9 ) + 2;
const int maxn = 1010;
struct node
{
int si,ni,ei,ti;
}a[210];
vector<int> vec;
struct Dinic
{
struct edge
{
int from,to,c,f;
edge(int getu,int getv,int getc,int getf)
{
from=getu;
to=getv;
c=getc;
f=getf;
}
};
int s,t,n;
int d[maxn];
int cur[maxn];
vector<edge> e;
vector<int> g[maxn];
void addedge(int u,int v,int c)
{
e.push_back(edge(u,v,c,0));
e.push_back(edge(v,u,0,0));
int m=e.size();
g[u].push_back(m-2);
g[v].push_back(m-1);
}
void init()
{
e.clear();
for(int i=0; i<maxn; i++)
g[i].clear();
}
bool bfs()
{
queue<int> q;
q.push(s);
memset(d,0,sizeof(d));
d[s]=1;
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=0; i<g[u].size(); i++)
{
int v=e[g[u][i]].to;
int c=e[g[u][i]].c;
int f=e[g[u][i]].f;
if(!d[v]&&c-f>0)
{
d[v]=d[u]+1;
q.push(v);
}
}
}
return d[t];
}
int dfs(int u,int maxf,int t)
{
if(u==t)return maxf;
int ret=0;
for(int &i=cur[u]; i<g[u].size(); i++)
{
int c=e[g[u][i]].c-e[g[u][i]].f;
int v=e[g[u][i]].to;
int f;
if(d[u]+1==d[v]&&c)
{
f=dfs(v,min(maxf-ret,c),t);
e[g[u][i]].f+=f;
e[g[u][i]^1].f-=f;
ret+=f;
if(ret==maxf)return ret;
}
}
return ret;
}
int maxflow(int s,int t)
{
this->s=s;
this->t=t;
int flow=0;
while(bfs())
{
memset(cur,0,sizeof(cur));
int temp=dfs(s,INF,t);
flow+=temp;
}
return flow;
}
}dinic;
int Contain(node a,int l,int r)
{
int L = a.si,R=a.ei;
if(l>R)return 1;
if(l>=L&&r<=R)return 2;
else return 3;
}
int main()
{
int n,lim;
// freopen("in.txt","r",stdin);
while(~scanf("%d%d",&n,&lim))
{
dinic.init();
vec.clear();
int si,ni,ei,ti,mf=0;
for(int i=1;i<=n;i++)
{
scanf("%d%d%d%d",&a[i].si,&a[i].ni,&a[i].ei,&a[i].ti);
mf+=a[i].ni*a[i].ti;
}
for(int i=1;i<=n;i++)
{
vec.push_back(a[i].si);
vec.push_back(a[i].ei);
}
int t=3*n+10;
sort(vec.begin(),vec.end());
unique(vec.begin(),vec.end());
for(int i=1,L=vec.size();i<L;i++)
dinic.addedge(n+i,t,(vec[i]-vec[i-1])*lim);
for(int i=1;i<=n;i++)
dinic.addedge(0,i,a[i].ti*a[i].ni);
for(int i=1;i<=n;i++)
{
for(int j=1,L=vec.size();j<L;j++)
{
int f=Contain(a[i],vec[j-1],vec[j]);
if(f==1)break;
if(f==2)dinic.addedge(i,n+j,INF);
else if(f==3)continue;
}
}
int maxflow=dinic.maxflow(0,t);
if(mf==maxflow)puts("Yes");
else puts("No");
}
}
/*
[1,2] 3
[2,4] 4
[4,6] 5
*/