题目链接:Task Schedule
题目大意:有n个任务和m个机器,一个任务需要ti的时间,只能从第s天开始,必须在第e天之前结束,问能不能把所有的任务都做完
题目思路:我们可以想到去建网络流,建一个超级源点0,然后第i个任务为点i,连接他和源点,容量为任务需要的天数(流出去的量嘛),然后每个任务和他的天数集合(从起点到终点)相连,容量为1,然后所有的天数和总计汇点连接,容量是m(最多只有m个机器嘛,同一天最多m个机器做工作),然后跑一遍最大流就好了
#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 1000+100;
const int MAXM = 1000000+10;
const int INF = 1000000+10;
struct Edge{
int from, to, cap, flow, next;
}edge[MAXM];
int dist[MAXN], vis[MAXN], cur[MAXN], top, head[MAXN];
int n, m;
int sumflow;
int sink;
void init(){
top = 0;
memset(head, -1, sizeof(head));
}
void addedge(int u, int v, int w){
Edge E1 = {u, v, w, 0, head[u]};
edge[top] = E1;
head[u] = top++;
Edge E2 = {v, u, 0, 0, head[v]};
edge[top] = E2;
head[v] = top++;
}
bool BFS(int start, int End){
queue<int> Q;
memset(dist, -1, sizeof(dist));
memset(vis, 0, sizeof(vis));
while(!Q.empty()) Q.pop();
Q.push(start);
vis[start] = 1;
dist[start] = 0;
while(!Q.empty()){
int u = Q.front();
Q.pop();
for(int i = head[u]; i != -1; i = edge[i].next){
Edge E = edge[i];
if(!vis[E.to] && E.cap > E.flow){
vis[E.to] = 1;
dist[E.to] = dist[u] + 1;
if(E.to == End) return true;
Q.push(E.to);
}
}
}
return false;
}
int DFS(int x, int a, int End){
if(x == End || 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), End)) > 0){
E.flow += f;
edge[i^1].flow -= f;
flow += f;
a -= f;
if(a == 0) break;
}
}
return flow;
}
int Dinic(int start, int End){
int flow = 0;
while(BFS(start, End)){
memcpy(cur, head, sizeof(head));
flow += DFS(start, INF, End);
}
return flow;
}
int main(){
int T,n,m;
scanf("%d",&T);
for(int Case = 1;Case <= T;Case++){
init();
scanf("%d%d",&n,&m);
int ti,s, e;
int last = 0;
sumflow = 0;
for(int i = 1; i <= n; i++){
scanf("%d%d%d", &ti, &s, &e);
sumflow += ti;
addedge(0, i, ti);
last = max(last, e);
for(int j = s; j <= e; j++)
addedge(i, n+j, 1);
}
sink = n+last+1;
for(int j = 1; j <= last; j++)
addedge(n+j, sink, m);
if(Dinic(0,sink) == sumflow) printf("Case %d: Yes\n\n",Case);
else printf("Case %d: No\n\n",Case);
}
return 0;
}