【題意】:給出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