思路:同hdu3572一样的模型。有n个客人,没人点了ni个烤肉串,其中没串需要ti的时间来烤熟,但是可以不是连续的ti时间,只要烤得时间加起来有ti就好了,与3752不同的是时间范围有点大,需要离散化一下,所以变成了区间。对起始时间排序去重,那么可以得到top个时间点,也就是top个区间,那么对于每个客人的时间要求,只要客人的要求[s,e] 完全包含了第i个区间,那么该客人与这个区间连边,容量inf,然后就是源点与客人连边,容量t*ni,最后就是时间区间与汇点连边,那么在这个时间区间内可以完成的烧烤时间任务必然是m * 区间宽度。
/***************************************** Author :Crazy_AC(JamesQi) Time :2015 File Name : *****************************************/ // #pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <algorithm> #include <iomanip> #include <sstream> #include <string> #include <stack> #include <queue> #include <deque> #include <vector> #include <map> #include <set> #include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> #include <limits.h> using namespace std; #define MEM(a,b) memset(a,b,sizeof a) typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> ii; const int inf = 1 << 30; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; inline int Readint(){ char c = getchar(); while(!isdigit(c)) c = getchar(); int x = 0; while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); } return x; } int n,m; const int maxn = 2200; const int maxm = 444444; int s[maxn],num[maxn],e[maxn],t[maxn]; int T[maxn * 2]; int cnt,top,tol; int head[maxn],pnt[maxm],nxt[maxm],cap[maxm]; void add(int u,int v,int c) { pnt[tol] = v;cap[tol] = c;nxt[tol] = head[u];head[u] = tol++; pnt[tol] = u;cap[tol] = 0;nxt[tol] = head[v];head[v] = tol++; } int d[maxn]; bool BFS(int st,int ed) { queue<int> que; memset(d, -1,sizeof d); d[st] = 0; que.push(st); while(!que.empty()) { int u = que.front(); que.pop(); // cout << "p\n"; for (int i = head[u];i != -1;i = nxt[i]) { int v = pnt[i]; if (cap[i] > 0 && d[v] == -1) { que.push(v); d[v] = d[u] + 1; } } } return d[ed] != -1; } int dfs(int u,int ed,int c) { if (u == ed) return c; for (int i = head[u];i != -1;i = nxt[i]) { int v = pnt[i]; if (cap[i] > 0 && d[v] == d[u] + 1) { int f = dfs(v,ed,min(cap[i],c)); if (f > 0){ cap[i] -= f; cap[i ^ 1] += f; return f; } } } return 0; } int DINIC(int st,int ed) { int flow = 0; while(BFS(st,ed)) { while(true) { int f = dfs(st,ed,inf); flow += f; if (f == 0) break; } } return flow; } int main() { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); while(~scanf("%d%d",&n,&m)){ cnt = tol = top = 0; int st = 0; int vt; int sum = 0; memset(head, -1,sizeof head); for (int i = 1;i <= n;i++){ scanf("%d%d%d%d",&s[i],&num[i],&e[i],&t[i]); T[cnt++] = s[i]; T[cnt++] = e[i]; sum += num[i] * t[i]; add(st,i,num[i] * t[i]); } /*离散化*/ sort(T,T + cnt); for (int i = 1;i < cnt;++i){ if (T[top] != T[i]) T[++top] = T[i]; } vt = top + n + 1;//汇点; for (int i = 1;i <= top;i++){ add(n + i,vt,m * (T[i] - T[i - 1])); for (int j = 1;j <= n;j++) if (s[j] <= T[i - 1] && e[j] >= T[i]) add(j,n + i,inf); } int ans = DINIC(st,vt); if (ans == sum) puts("Yes"); else puts("No"); } return 0; }