给定n个顾客,第i号顾客在si到达,点了ni个羊肉串,每个羊肉串需要ti个时间烤好。顾客想要在ei得到,一个烤炉只烤m串。问你是否能满足所有顾客的要求?能的话输出“Yes”,否则输出“No”。注意:这ni个羊肉串可以被分开来考,一个单独的羊肉串也能分开烤(比如一个单独的羊肉串需要ti时间,我们把它分成ti份同时烤的话,那么一个羊肉串可以在1个单位时间内拷完)
注意:每个顾客的任务必须在(si,ei]半开半闭的区间内完成.
分析:和这个题很像:HDU3572
这个题时间区间比较大,但是个数并不多,把时间区间给拆出来,离散化一下,然后就是普通的建图了(二层结构);
这个建图真恶心,思路有了,建图一直错。。。就是把整个大的时间区间保存下,就是一个线段一个区间进行离散化。第一层是源点到每一个任务(1~n),权值是ni * ti;第二层是任务到时间区间,权值是:时间区间长度 * 机器数;最后把时间区间连到汇点,权值是时间区间*机器数;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
typedef long long LL;
using namespace std;
const int MAXN = 1000 + 5;
const int INF = 0x3f3f3f3f;
int head[MAXN], dist[MAXN], vis[MAXN];
int cur[MAXN], si[MAXN], ei[MAXN], a[MAXN << 1];
int top = 0;
struct Edge {
int to, cap, flow, next;
}edge[MAXN * 10];
void init() {
top = 0;
memset(head, -1, sizeof(head));
memset(vis, 0, sizeof(vis));
}
void addedge(int a, int b, int c) {
Edge E1 = {b, c, 0, head[a]};
edge[top] = E1;
head[a] = top++;
Edge E2 = {a, 0, 0, head[b]};
edge[top] = E2;
head[b] = top++;
}
bool BFS(int st, int ed) {
memset(dist, -1, sizeof(dist));
memset(vis, 0, sizeof(vis));
queue<int> que;
que.push(st);
vis[st] = 1;
dist[st] = 0;
while(!que.empty()) {
int u = que.front();
que.pop();
for(int i = head[u]; i != -1; i = edge[i].next) {
Edge E = edge[i];
if(!vis[E.to] && E.cap > E.flow) {
dist[E.to] = dist[u] + 1;
vis[E.to] = 1;
if(E.to == ed) return true;
que.push(E.to);
}
}
}
return false;
}
int DFS(int x, int a, int ed) {
if(x == ed || a == 0) return a;
int flow = 0, f;
for(int& i = cur[x]; i != -1; i = edge[i].next) {
Edge& E = edge[i];
if(dist[E.to] == dist[x] + 1 && (f = DFS(E.to, min(a, E.cap - E.flow), ed)) > 0) {
E.flow += f;
edge[i^1].flow -= f;
flow += f;
a -= f;
if(a == 0) break;
}
}
return flow;
}
int Maxflow(int st, int ed) {
int flow = 0;
while(BFS(st, ed)) {
memcpy(cur, head, sizeof(head));
flow += DFS(st, INF, ed);
}
return flow;
}
int main()
{
int n, m;
while(scanf("%d %d", &n, &m) != EOF) {
init();
int ni, ti, sum = 0;
for(int i = 1; i <= n; ++i) {
scanf("%d %d %d %d", &si[i], &ni, &ei[i], &ti);
sum += ni * ti;
addedge(0, i, ni * ti);
a[i] = si[i];
a[i + n] = ei[i];
}
sort(a + 1, a + n + n + 1);
int ans = n + n;
for(int i = 2; i <= ans; ++i) {
addedge(i + n - 1, ans + 2 + n, (a[i] - a[i - 1]) * m);
for(int j = 1; j <= n; ++j) {
if(si[j] <= a[i - 1] && a[i] <= ei[j]) {
addedge(j, i + n - 1, (a[i] - a[i - 1]) * m);
}
}
}
if(Maxflow(0, ans + n + 2) < sum) puts("No");
else puts("Yes");
}
return 0;
}