【题意】:给出n个任务和m个机器,每个机器每天只能运行一个任务。对于每个任务,有三个属性p,s,e,表示这个任务至少要在s天后开始运行,至多要在e天前结束运行,并且需要运行p天。问是否存在一种方案使得这n个任务都完成。

【题解】:用网络流来判断是否可行。
              把每个任务看成一个点,s到每个任务连边,容量为任务需要运行的天数。
              把每天看成一个点,每天向t连边,容量为m,表示一天最多运行m个任务。
              每个任务都向s-e天连边,容量为1,表示这个任务可以在这些天运行。
              最后判断最大流是否等于所有任务需要运行的天数总和即可。

【代码】:
  1 #include "iostream"
  2 #include "cstdio"
  3 #include "cstring"
  4 #include "algorithm"
  5 #include "vector"
  6 #include "queue"
  7 #include "cmath"
  8 #include "string"
  9 #include "cctype"
 10 #include "map"
 11 #include "iomanip"
 12 #include "set"
 13 #include "utility"
 14 using namespace std;
 15 typedef pair<intint> pii;
 16 #define pb push_back
 17 #define mp make_pair
 18 #define fi first
 19 #define se second
 20 #define sof(x) sizeof(x)
 21 #define lc(x) (x << 1)
 22 #define rc(x) (x << 1 | 1)
 23 #define lowbit(x) (x & (-x))
 24 #define ll long long
 25 
 26 const int inf = 1 << 30;
 27 #define maxn 1500
 28 #define maxm 1000000
 29 int n, m, s, t;
 30 int eh[maxn], low[maxn], dist[maxn], pre[maxn], cur[maxn], tot, cnt[maxn];
 31 struct Edge {
 32     int u, v, cap, flow, next;
 33 }et[maxm];
 34 void init() {
 35     tot = 0;
 36     memset(eh, -1, sizeof(eh));
 37 }
 38 void add(int u, int v, int cap, int flow) {
 39     Edge e = {u, v, cap, flow, eh[u]};
 40     et[tot] = e;
 41     eh[u] = tot++;
 42 }
 43 void addedge(int u, int v, int cap) {
 44     add(u, v, cap, 0), add(v, u, 0, 0);
 45 }
 46 int isap(int s, int t, int n){
 47     int u, v, now, flow = 0;
 48     memset(dist, 0, sizeof(dist)); 
 49     memset(low, 0, sizeof(low));
 50     memset(cnt, 0, sizeof(cnt));
 51     for(u = 0 ; u <= n ; u ++) cur[u] = eh[u];
 52     low[s] = inf, cnt[0] = n, u = s;
 53     while(dist[s] < n) {
 54         for(now = cur[u]; now != -1; now = et[now].next)
 55             if(et[now].cap - et[now].flow && dist[u] == dist[ v = et[now].v ] + 1 ) break;
 56         if(now != -1) {
 57             cur[u] = pre[v] = now;
 58             low[v] = min(et[now].cap - et[now].flow, low[u]);
 59             u = v;
 60             if(u == t) {
 61                 for(; u != s; u = et[pre[u]].u){
 62                     et[pre[u]].flow += low[t];
 63                     et[pre[u]^1].flow -= low[t];
 64                 }
 65                 flow += low[t]; low[s] = inf;
 66             }
 67         } else {
 68             if(--cnt[dist[u]] == 0) break;
 69             dist[u] = n, cur[u] = eh[u];
 70             for(now = eh[u]; now != -1; now = et[now].next)
 71                 if(et[now].cap - et[now].flow && dist[u] > dist[et[now].v] + 1)
 72                     dist[u] = dist[ et[now].v ] + 1;
 73             cnt[dist[u]]++;
 74             if(u != s) u = et[pre[u]].u;
 75         }
 76     }
 77     return flow;
 78 }
 79 
 80 int main() {
 81     int T, Case = 1;
 82     scanf("%d", &T);
 83     while(T--) {
 84         scanf("%d%d", &n, &m);
 85         init();
 86         s = 0, t = n + 500 + 1;
 87         int sum = 0;
 88         for(int i = 1; i <= n; i++) {
 89             int p, start, end;
 90             scanf("%d%d%d", &p, &start, &end);
 91             sum += p;
 92             addedge(s, i, p);
 93             for(int j = start; j <= end; j++) {
 94                 addedge(i, n + j, 1);
 95             }
 96         }
 97         printf("Case %d: ", Case++);
 98         for(int i = 1; i <= 500; i++) addedge(i + n, t, m);
 99         if(sum == isap(s, t, 2 + n + 500)) puts("Yes");
100         else puts("No");
101         cout << endl;
102     }
103     return 0;
104 }
105